Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Log Everything with Fluentd
Search
Kentaro Kuribayashi
February 15, 2013
Technology
4.2k
4
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Log Everything with Fluentd
Kentaro Kuribayashi
February 15, 2013
More Decks by Kentaro Kuribayashi
See All by Kentaro Kuribayashi
あとはAIに任せて人間は自由に生きる
kentaro
5
2.2k
社会人力と研究力ー博士号をキャリアの武器にするー
kentaro
3
330
IoTシステム開発の複雑さを低減するための統合的アーキテクチャ
kentaro
2
2.5k
Bidirectional Quadratic Voting Leveraging Issue-Based Matching
kentaro
2
790
大高生へのメッセージ(令和6年度「大高未来塾」) / Messages to Current Students
kentaro
0
350
「始め方」の始め方 / How to Start Starting Things
kentaro
5
1k
Dynamic IoT Applications and Isomorphic IoT Systems Using WebAssembly
kentaro
1
1.7k
わたしがこのところハマっている「ライセンスフリー無線」のご紹介 / An Invitation to License-Free Radio
kentaro
1
780
先行きの見えなさを楽しさに変える ーVUCA時代のキャリア論と絶対他力主義ー / How to develop your career in the VUCA era
kentaro
8
6.9k
Other Decks in Technology
See All in Technology
AI x 開発生産性を取り巻く予算戦略と投資対効果
i35_267
7
2.8k
reFACToring
moznion
0
130
Jitera Company Deck
jitera
0
270
クラウドを使う側から、作る側へ / 大吉祥寺.pm 2026前夜祭
fujiwara3
4
1.1k
複数プロダクトで進めるAI機能実装 ── 実践から得たリアルな学びとロードマップ実現への挑戦 / AICon2026_yanari
rakus_dev
1
270
AIエージェントがあれば技術書なんてすぐ書けるでしょ→無理でした
watany
2
180
GoでCコンパイラを作った話
repunit
0
150
全社でのソフトウェアサプライチェーン攻撃対策をやってみた with Takumi Guard
z63d
0
260
”AIを使う” から ”AIに任せる” へ ─ 開発プロセスを再設計してAIを組織標準にするまで
cyberagentdevelopers
PRO
1
140
SoccerMaster: A Vision Foundation Model for Soccer Understanding
kzykmyzw
0
160
PHPで作って学ぶリアルタイム音声対話AIとWebSocket入門 by ムナカタ
munakata
0
130
大量データに対しても、生成AIを用いてリーズナブルにデータ加工をしたい!Databricksのai_queryについて調べてみた
kamoshika
1
280
Featured
See All Featured
What the history of the web can teach us about the future of AI
inesmontani
PRO
1
640
Building Flexible Design Systems
yeseniaperezcruz
330
40k
Ethics towards AI in product and experience design
skipperchong
2
330
Embracing the Ebb and Flow
colly
88
5.1k
How to audit for AI Accessibility on your Front & Back End
davetheseo
0
470
Done Done
chrislema
186
16k
Learning to Love Humans: Emotional Interface Design
aarron
275
41k
[SF Ruby Conf 2025] Rails X
palkan
2
1.2k
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
234
17k
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
360
30k
Dealing with People You Can't Stand - Big Design 2015
cassininazir
367
27k
The Pragmatic Product Professional
lauravandoore
37
7.4k
Transcript
Log Everything @kentaro
@kentaro Software engineer Rubyist / Perl Monger Kentaro Kuribayashi paperboy&co.
PHPer
None
Contributions to Fluentd World
out_flatten https://github.com/kentaro/fluent-plugin-flatten out_extract_query_params https://github.com/kentaro/fluent-plugin-extract_query_params out_rewrite https://github.com/kentaro/fluent-plugin-rewrite
None
Log Format
None
• Easy to extend • Easy to parse
Key Description Apache Nginx time Time request is received %t
$time_local vhost Host name %v $host host Remote host %h $remote_addr method Request method %m $method path Request path %U%q $request_uri version HTTP version %H $server_protocol status Response status %>s $status size Response size %b $body_bytes_sent referer Referer %{Referer}i $http_referer ua User-agent %{User-Agent}i $http_user_agent restime Time elapsed for response %D $request_time ustime Time elapsed for upstream response - $upstream_response_time
LogFormat "vhost:%V\ttime:%t\thost:%h\tmethod:%m\tpath:%U%q \tversion:%H\tstatus:%>s\tsize:%b\treferer:%{Referer}i\tua: %{User-Agent}i\trestime:%D" ltsv log_format ltsv "vhost:$host\ttime:$time_local\thost: $remote_addr\tmethod:$request_method\tpath:$request_uri \tversion:$server_protocol\tstatus:$status\tsize:
$body_bytes_sent\treferer:$http_referer\tua: $http_user_agent\trestime:$request_time\tustime: $upstream_response_time"; Apache Nginx
Log Everything to Access Log File
with Log Everything to Access Log File
fluent-plugin-php
None
apache_note()
%{foo}n #=> bar apache_note(‘foo’, ‘bar’) PHP Code Apache Log Format
Flags
• URL Groups • User/Guest • Device • Bot Access
• etc.
Structuralize URLs • Visualization • Analysis • Rough grouping is
enough
Group Path read ^/book buy ^/cart ^/book/\d+/purchase find ^/special ^/label
^/users ^/books ^/authors write ^/admin ^/users/{account}/draft set ^/users/{account}/manage ^/users/{account}/profile ^/users/{account}/account communicate ^/users/{account}/contact ^/users/{account}/reaction top ^/$ ^$
out_rewrite
<match apache.log.**> type rewrite remove_prefix apache.log add_prefix filtered # url
group <rule> key uriGroup pattern ^(.+)$ append_to_tag true fallback other </rule> ...
... # pc/smartphone <rule> key device pattern ^(pc|sp)$ append_to_tag true
</rule> ...
... # user/guest <rule> key loggedIn pattern ^(user|guest)$ append_to_tag true
</rule> </match>
filtered.book.pc.user => { ... } filtered.book.sp.guest => { ... }
filtered.read.pc.guest => { ... } ... uriGroup:book device:pc loggedIn:user ... ... uriGroup:book device:sp loggedIn:guest ... ... uriGroup:read device:pc loggedIn:guest ... Raw Log Lines Filtered Key/Values
None
Profiling
Problem Hard to track results continuously
class Foo { function hoge () { $this->profiler->start(‘method-hoge’); // ...
do something ... $this->profiler->end(‘method-hoge’); } function fuga () { $this->profiler->start(‘method-fuga-foo’); // ... do something ... $this->profiler->end(‘method-fuga-foo’); $this->profiler->start(‘method-fuga-bar’); // ... do something ... $this->profiler->end(‘method-fuga-bar’); } }
public function dispatchLoopShutdown() { $profile_result = Model_Measure::dump(); if (APPLICATION_ENV !==
'production') { Pb_Logger::debug($profile_result); } Pb_Util::httpd_note('profile', json_encode($profile_result)); }
static public function httpd_note($name, $value = '') { if (function_exists('apache_note'))
{ if ($value) { return apache_note($name, $value); } else { // do nothing... } } }
... profile:%{profile}n" ... profile:{\"book.index.get_book\":0.1010639667511, \"book.index.get_author\":0.2032630443573, \"book.index.get_chapters\":0.23988509178162, \"book.index.get_version\":0.039833068847656, \"book.index.check\":0.00014090538024902, \"book.index.get_pager\":0.00022792816162109} Log
Format Raw Log Line
out_flatten
<match test.**> type flatten key foo add_tag_prefix flattened. remove_tag_prefix test.
inner_key value_for_flat_key </match> "test" => { "foo" => '{"bar" : {"qux" : "quux", "hoe" : "poe" }, "baz" : "bazz" }', "hoge" => "fuga" } "flattened.foo.bar.qux" => { "value_for_flat_key" => "quux" } "flattened.foo.bar.hoe" => { "value_for_flat_key" => "poe" } "flattened.foo.baz" => { "value_for_flat_key" => "bazz" } flattened
<match app.httpd.access> type flatten key profile inner_key response_time add_tag_prefix flattened.
remove_tag_prefix app.httpd.access. </store>
None
None
Bonus
out_extract_query_params
<match test.**> type extract_query_params key url add_tag_prefix extracted. only foo,
baz </match> "test" => { "url" => "http://example.com/?foo=bar&baz=qux&hoge=fuga" } "extracted.test" => { "url" => "http://example.com/?foo=bar&baz=qux&hoge=fuga" "foo" => "bar", "baz" => "qux" } Extract Params
<match access_log> type extract_query_params key path add_tag_prefix extracted. only hoge
</match> method:%m path:%U%q version:%H #=> method:GET path:/foo/bar?campaign_id=1 version:HTTP1.1 extracted.access_log => { "method" : "GET", "path" : "/foo/bar?campaign_id=1", "version" : "HTTP1.1", "campaign_id" : "1" } Extract Params Works fine with LTSV
Recap
• Adopt LTSV asap • Log things as much as
possible • My plugins help you