LARAVEL – Logging
Following the series about laravel in production
, this article I will share about the implementation of log
on laravel server.
1. Introduction to laravel logging
Imagine, one fine day, you are sipping a cup of coffee and chill
to the tune you love. BOOM , you received an error điều tra
ticket and you need to answer: why did it happen, how much impact is it, how do you handle it? Okie, that’s simple, let’s check the log
. After reading the logs on the server, filter the types. You realize, there is no log required to investigate cái lỗi này
The above is just one case có thể
have encountered while working. And after ticket investigation, almost all of us realize the importance of log
and ghi lại
the necessary information to serve investigation as well as tracing errors.
Fortunately, in laravel, logging is quite simple.
1 2 | Log <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token function">debug</span> <span class="token punctuation">(</span> <span class="token variable">$message</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> |
Log level
By default, laravel supports the following log levels: emergency
, alert
, critical
, error
, warning
, notice
, info
, debug
Depending on mức độ
you will choose the appropriate level to log.
1 2 3 4 5 6 7 8 9 | Log <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token function">emergency</span> <span class="token punctuation">(</span> <span class="token variable">$message</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> Log <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token function">alert</span> <span class="token punctuation">(</span> <span class="token variable">$message</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> Log <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token function">critical</span> <span class="token punctuation">(</span> <span class="token variable">$message</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> Log <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token function">error</span> <span class="token punctuation">(</span> <span class="token variable">$message</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> Log <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token function">warning</span> <span class="token punctuation">(</span> <span class="token variable">$message</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> Log <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token function">notice</span> <span class="token punctuation">(</span> <span class="token variable">$message</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> Log <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token function">info</span> <span class="token punctuation">(</span> <span class="token variable">$message</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> Log <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token function">debug</span> <span class="token punctuation">(</span> <span class="token variable">$message</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> |
Log driver
According to laravel documentation, laravel supports the following channels:
Name | description |
---|---|
stack | A wrapper to facilitate creating “multi-channel” channels |
single | A single file or path based logger channel (StreamHandler) |
daily | A RotatingFileHandler based Monolog driver which rotates daily |
slack | A SlackWebhookHandler based Monolog driver |
papertrail | A SyslogUdpHandler based Monolog driver |
syslog | A SyslogHandler based Monolog driver |
errorlog | A ErrorLogHandler based Monolog driver |
monolog | A Monolog factory driver that may use any supported Monolog handler |
custom | A driver that calls a specified factory to create a channel |
Note: You can understand that the driver is the method that we will record the log
For example:
- single: you will write the log of each day to 1 file
- slack: you will send log into a slack channel
2. Logging in production
How to use log is quite simple, however, where to put the log, what information to log, we have a headache. If we log all information, it will be too wasteful of the system’s resources. Log is incomplete, in the wrong place, we do not have enough data for investigation.
Here are some of the things that I have learned in the process of working with logs in real projects
Permission
Oh, there is nothing wrong with permission
to pay attention: lol:
1 2 3 4 5 6 7 8 9 10 11 | <span class="token comment">// config/logging.php</span> <span class="token single-quoted-string string">'channels'</span> <span class="token operator">=</span> <span class="token operator">></span> <span class="token punctuation">[</span> <span class="token single-quoted-string string">'daily'</span> <span class="token operator">=</span> <span class="token operator">></span> <span class="token punctuation">[</span> <span class="token single-quoted-string string">'driver'</span> <span class="token operator">=</span> <span class="token operator">></span> <span class="token single-quoted-string string">'daily'</span> <span class="token punctuation">,</span> <span class="token single-quoted-string string">'path'</span> <span class="token operator">=</span> <span class="token operator">></span> <span class="token function">storage_path</span> <span class="token punctuation">(</span> <span class="token single-quoted-string string">'logs/laravel.log'</span> <span class="token punctuation">)</span> <span class="token punctuation">,</span> <span class="token single-quoted-string string">'level'</span> <span class="token operator">=</span> <span class="token operator">></span> <span class="token single-quoted-string string">'debug'</span> <span class="token punctuation">,</span> <span class="token single-quoted-string string">'days'</span> <span class="token operator">=</span> <span class="token operator">></span> <span class="token number">0</span> <span class="token punctuation">,</span> <span class="token single-quoted-string string">'permission'</span> <span class="token operator">=</span> <span class="token operator">></span> <span class="token number">0755</span> <span class="token punctuation">,</span> <span class="token punctuation">]</span> <span class="token punctuation">,</span> <span class="token comment">//....</span> |
Setting permissions for the incorrect log files will significantly affect a number of tasks related to log files. Eg:
- Saving. For some projects, you store logs on the server, not using 3rd party services to manage logs. So to optimize system resources, we often have to run tasks to zip, move files to another server for storage.
- Deploying. The deployment of the current system, we often use the tool support like
rocketeer
,deployer
,capistrano
. Thestorage
directory – usually where you store logs – is the directory that is usually shared between releases and servers (in case the system runs multiple servers). So, if you don’t set the right permissions, you will get an error when doing auto-deploy, creating a symbolic link or copying the storage directory, for example. - Viewing.
"Em ơi, có lỗi rồi! lên server check giúp anh/chị"
, do you think this sentence is familiar: lol: Ssh on the server and check log is usually inevitable. If the user you use tossh
does not have permission to read the log file, you will lose thechmod
tochmod
it. Even if you don’t havesudo
privileges, there’s nothing you can do about it =))
Log channel
Using the default channel
takes a lot of work to investigate, especially when logging data is large. Everything will be mixed together and you need to filter a lot to get the data you want.
For my project, my team performs functional logging. Like the login / logout function, I will use a separate channel. Or the feature of tagging and tagging, I also use my own channel. This helps me quite a lot when you need to investigate a specific feature.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | <span class="token comment">// config/logging.php</span> <span class="token single-quoted-string string">'login_history'</span> <span class="token operator">=</span> <span class="token operator">></span> <span class="token punctuation">[</span> <span class="token single-quoted-string string">'driver'</span> <span class="token operator">=</span> <span class="token operator">></span> <span class="token single-quoted-string string">'single'</span> <span class="token punctuation">,</span> <span class="token single-quoted-string string">'path'</span> <span class="token operator">=</span> <span class="token operator">></span> <span class="token function">storage_path</span> <span class="token punctuation">(</span> <span class="token single-quoted-string string">'logs/login_history.log'</span> <span class="token punctuation">)</span> <span class="token punctuation">,</span> <span class="token single-quoted-string string">'level'</span> <span class="token operator">=</span> <span class="token operator">></span> <span class="token single-quoted-string string">'debug'</span> <span class="token punctuation">,</span> <span class="token single-quoted-string string">'permission'</span> <span class="token operator">=</span> <span class="token operator">></span> <span class="token number">0755</span> <span class="token punctuation">,</span> <span class="token punctuation">]</span> <span class="token punctuation">,</span> <span class="token single-quoted-string string">'tag_logging'</span> <span class="token operator">=</span> <span class="token operator">></span> <span class="token punctuation">[</span> <span class="token single-quoted-string string">'driver'</span> <span class="token operator">=</span> <span class="token operator">></span> <span class="token single-quoted-string string">'daily'</span> <span class="token punctuation">,</span> <span class="token single-quoted-string string">'path'</span> <span class="token operator">=</span> <span class="token operator">></span> <span class="token function">storage_path</span> <span class="token punctuation">(</span> <span class="token single-quoted-string string">'logs/tags.log'</span> <span class="token punctuation">)</span> <span class="token punctuation">,</span> <span class="token single-quoted-string string">'level'</span> <span class="token operator">=</span> <span class="token operator">></span> <span class="token single-quoted-string string">'debug'</span> <span class="token punctuation">,</span> <span class="token single-quoted-string string">'days'</span> <span class="token operator">=</span> <span class="token operator">></span> <span class="token number">0</span> <span class="token punctuation">,</span> <span class="token single-quoted-string string">'permission'</span> <span class="token operator">=</span> <span class="token operator">></span> <span class="token number">0755</span> <span class="token punctuation">,</span> <span class="token punctuation">]</span> <span class="token punctuation">,</span> <span class="token comment">// somewhere....</span> Log <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token function">channel</span> <span class="token punctuation">(</span> <span class="token single-quoted-string string">'login_history'</span> <span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">info</span> <span class="token punctuation">(</span> <span class="token variable">$info</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> Log <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token function">channel</span> <span class="token punctuation">(</span> <span class="token single-quoted-string string">'tag_logging'</span> <span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">debug</span> <span class="token punctuation">(</span> <span class="token variable">$info</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> |
Exception handler
This is pretty much what you already know, and it’s obvious when it comes to recording errors when an exception occurs.
Laravel has a Handler
to handle whenever an exception occurs. This class contains two methods: report
and render
. The render
method will let us choose how the exception is logged, usually we use the default. The report
method also converts the exception and writes it back to the log file.
However, we usually do the reporting right after the exception has occurred to get the necessary responses. Depending on the project, you can post information on sentry
, bugsnag
or slack
, chatwork
There is quite a bit of useful information included in the exception that you can get for logging and reporting. Here is the example that we use (send messages to slack
and chatwork
):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | <span class="token php language-php"><span class="token delimiter important"><?php</span> <span class="token comment">// app/Exceptions/Handler.php</span> <span class="token comment">/** * Report or log an exception. * * @param Exception $exception * @return mixed|void * @throws Exception */</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">report</span> <span class="token punctuation">(</span> Exception <span class="token variable">$exception</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">parent</span> <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token function">report</span> <span class="token punctuation">(</span> <span class="token variable">$exception</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token variable">$this</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">handleNotification</span> <span class="token punctuation">(</span> <span class="token variable">$exception</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/** * Handle notification * * @param Exception $exception * @return void */</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">handleNotification</span> <span class="token punctuation">(</span> Exception <span class="token variable">$exception</span> <span class="token punctuation">)</span> <span class="token punctuation">:</span> void <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> <span class="token variable">$this</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">shouldntReport</span> <span class="token punctuation">(</span> <span class="token variable">$exception</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token variable">$title</span> <span class="token operator">=</span> <span class="token function">get_class</span> <span class="token punctuation">(</span> <span class="token variable">$exception</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token comment">// Get class đã gây ra lỗi</span> <span class="token variable">$trance</span> <span class="token operator">=</span> <span class="token variable">$exception</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">getTraceAsString</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token comment">// Lấy stack trace</span> <span class="token variable">$e</span> <span class="token operator">=</span> <span class="token variable">$this</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">convertException</span> <span class="token punctuation">(</span> <span class="token variable">$exception</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token comment">// Lấy thông tin của file và line lỗi</span> <span class="token variable">$auth</span> <span class="token operator">=</span> <span class="token variable">$this</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">getAuth</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token comment">// Lấy thông tin của user gây lỗi</span> <span class="token variable">$url</span> <span class="token operator">=</span> <span class="token variable">$this</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">getUrl</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token comment">// Url gặp lỗi</span> <span class="token variable">$gitInfo</span> <span class="token operator">=</span> <span class="token variable">$this</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">getGitInfo</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token comment">// Version của git</span> <span class="token variable">$infoServer</span> <span class="token operator">=</span> <span class="token variable">$this</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">getInfoServer</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token comment">// Thông tin của server (ip)</span> <span class="token variable">$context</span> <span class="token operator">=</span> <span class="token variable">$e</span> <span class="token operator">+</span> <span class="token variable">$auth</span> <span class="token operator">+</span> <span class="token variable">$url</span> <span class="token operator">+</span> <span class="token variable">$gitInfo</span> <span class="token operator">+</span> <span class="token variable">$infoServer</span> <span class="token operator">+</span> <span class="token variable">$dataLine</span> <span class="token punctuation">;</span> <span class="token comment">// Send exception to slack</span> <span class="token variable">$detail</span> <span class="token operator">=</span> <span class="token variable">$this</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">getDetailException</span> <span class="token punctuation">(</span> <span class="token variable">$exception</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token comment">// Trim $exception->toString()</span> <span class="token variable">$this</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">toSlack</span> <span class="token punctuation">(</span> <span class="token variable">$title</span> <span class="token punctuation">,</span> <span class="token variable">$context</span> <span class="token operator">+</span> <span class="token variable">$detail</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token comment">// Tửi tin nhắn tới slack</span> <span class="token comment">// Send exception to chatwork</span> <span class="token variable">$detail</span> <span class="token operator">=</span> <span class="token variable">$this</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">getDetailException</span> <span class="token punctuation">(</span> <span class="token variable">$exception</span> <span class="token punctuation">,</span> <span class="token variable">$this</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token property">limitString</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token comment">// Trim $exception->toString()</span> <span class="token variable">$this</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">toChatwork</span> <span class="token punctuation">(</span> <span class="token variable">$title</span> <span class="token punctuation">,</span> <span class="token variable">$context</span> <span class="token operator">+</span> <span class="token variable">$detail</span> <span class="token punctuation">,</span> <span class="token variable">$trance</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token comment">// Gửi tin nhắn tới chatwork</span> <span class="token punctuation">}</span> </span> |
If you don’t want to report
some exception
, you can add it to the $dontReport
variable in Handler
. It will automatically filter and report only the appropriate exceptions.
1 2 3 4 5 6 7 8 | <span class="token keyword">protected</span> <span class="token variable">$dontReport</span> <span class="token operator">=</span> <span class="token punctuation">[</span> <span class="token package">Illuminate Auth AuthenticationException</span> <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token keyword">class</span> <span class="token punctuation">,</span> <span class="token package">Illuminate Auth Access AuthorizationException</span> <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token keyword">class</span> <span class="token punctuation">,</span> <span class="token package">Symfony Component HttpKernel Exception HttpException</span> <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token keyword">class</span> <span class="token punctuation">,</span> <span class="token package">Illuminate Database Eloquent ModelNotFoundException</span> <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token keyword">class</span> <span class="token punctuation">,</span> <span class="token package">Illuminate Validation ValidationException</span> <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token keyword">class</span> <span class="token punctuation">,</span> <span class="token punctuation">]</span> <span class="token punctuation">;</span> |
Database logging
Above we have done the saving of the action logs on the laravel system. However, sometimes incorrect logic leads to improper data storage. It is also possible that the query is too large and the query’s execution will cause errors. So what do we need to do?
Record log before manipulating database? This can be done but you need to repeat the code in rất rất nhiều
places, and maybe forget some places. There is a more optimal way, we will use the available method DB::listen()
so that every time we have a database action, we will record the query. You can also filter
to avoid logging unnecessary queries
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | <span class="token comment">// AppServiceProvider</span> <span class="token comment">/** * Register any application services. * * @return void */</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">register</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token constant">DB</span> <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token function">listen</span> <span class="token punctuation">(</span> <span class="token keyword">function</span> <span class="token punctuation">(</span> <span class="token variable">$query</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">try</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> <span class="token variable">$this</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">filterQuery</span> <span class="token punctuation">(</span> <span class="token variable">$query</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> Log <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token function">channel</span> <span class="token punctuation">(</span> <span class="token single-quoted-string string">'query_history'</span> <span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">debug</span> <span class="token punctuation">(</span> <span class="token double-quoted-string string">"QUERY TIME: <span class="token interpolation"><span class="token punctuation">{</span> <span class="token variable">$query</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token property">time</span> <span class="token punctuation">}</span></span> , EXECUTE SQL: <span class="token interpolation"><span class="token punctuation">{</span> <span class="token variable">$sql</span> <span class="token punctuation">}</span></span> "</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span> <span class="token package">Exception</span> <span class="token variable">$e</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> Log <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token function">info</span> <span class="token punctuation">(</span> <span class="token variable">$e</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// ...</span> |
Log Formatter
The nice thing about laravel is that laravel allows us to change the default format when logging to logs and you can format it theo ý của mình
. This one I never used, found it nice, so I added it: 3
You need to create 1 CustomizeFormatter
and update config of channel
, add 'tap' => [AppLoggingCustomizeFormatter::class]
as below:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | // config/logging.php 'single' => [ 'driver' => 'single', 'tap' => [AppLoggingCustomizeFormatter::class], 'path' => storage_path('logs/laravel.log'), 'level' => 'debug', ], // appLoggingCustomizeFormatter.php <span class="token php language-php"><span class="token delimiter important"><?php</span> <span class="token keyword">namespace</span> <span class="token package">App Logging</span> <span class="token punctuation">;</span> <span class="token keyword">use</span> <span class="token package">Monolog Formatter LineFormatter</span> <span class="token punctuation">;</span> <span class="token keyword">class</span> <span class="token class-name">CustomizeFormatter</span> <span class="token punctuation">{</span> <span class="token comment">/** * Customize the given logger instance. * * @param IlluminateLogLogger $logger * @return void */</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">__invoke</span> <span class="token punctuation">(</span> <span class="token variable">$logger</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">foreach</span> <span class="token punctuation">(</span> <span class="token variable">$logger</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">getHandlers</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token keyword">as</span> <span class="token variable">$handler</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token variable">$handler</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">setFormatter</span> <span class="token punctuation">(</span> <span class="token keyword">new</span> <span class="token class-name">LineFormatter</span> <span class="token punctuation">(</span> <span class="token single-quoted-string string">'[%datetime%] %channel%.%level_name%: %message% %context% %extra%'</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> </span> |
Log Viewing
Each of you, each project will have a different way of đọc
logs. How do you normally read the log? Here are some of the ways that I used to get log and read.
ssh
to the server, read each file. If the number of servers is large or the number of files to check is large, this is not reasonable. Also you need to have ssh permission to the server and know how to usevim
- Download log from server to local computer and use some editor to
find
. This is fine, but like the one above, you need to have ssh permission to the server to download the file. We can automate it by writingscript
(usingrsync
orscp
) or using tools likeansible
- Use third-party apps like
sentry
,bugsnag
. I just need to login and see it. - Use
FILE_DRIVER
partyFILE_DRIVER
(such asaws s3
, …). Similar to above, just go to theamazon console
and filter.
Epilogue
Above, I just mentioned how to log, not to mention how to set the log. How to set the log, the proper position it depends on a lot of developers as well as their experience. It doesn’t have a standard. There’s only one thing I think we should adhere to: chỉ log những thông tin cần thiết