<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE erlref SYSTEM "erlref.dtd">

<erlref>
  <header>
    <copyright>
      <year>2017</year><year>2020</year>
      <holder>Ericsson AB. All Rights Reserved.</holder>
    </copyright>
    <legalnotice>
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at

          http://www.apache.org/licenses/LICENSE-2.0

      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      See the License for the specific language governing permissions and
      limitations under the License.

    </legalnotice>

    <title>logger_std_h</title>
    <prepared></prepared>
    <responsible></responsible>
    <docno></docno>
    <approved></approved>
    <checked></checked>
    <date></date>
    <rev>A</rev>
    <file>logger_std_h.xml</file>
  </header>
  <module since="OTP 21.0">logger_std_h</module>
  <modulesummary>Standard handler for Logger.</modulesummary>

  <description>
    <p>This is the standard handler for Logger.
      Multiple instances of this handler can be added to
      Logger, and each instance prints logs to <c>standard_io</c>,
      <c>standard_error</c>, or to file.</p>
    <p>The handler has an overload protection mechanism that keeps the handler
      process and the Kernel application alive during high loads of log 
      events. How overload protection works, and how to configure it, is
      described in the
      <seeguide marker="logger_chapter#overload_protection"><c>User's Guide</c>
      </seeguide>.</p>
    <p>To add a new instance of the standard handler, use
      <seemfa marker="logger#add_handler/3"><c>logger:add_handler/3</c>
      </seemfa>. The handler configuration argument is a map which can contain
      general configuration parameters, as documented in the
       <seeguide marker="logger_chapter#handler_configuration"><c>User's Guide</c>
       </seeguide>, and handler specific parameters. The specific data
       is stored in a sub map with the key <c>config</c>, and can contain the
       following parameters:</p>
    <taglist>
      <tag><marker id="type"/><c>type = standard_io | standard_error | file | {device, io:device()}</c></tag>
      <item>
	<p>Specifies the log destination.</p>
	<p>The value is set when the handler is added, and it cannot
	  be changed in runtime.</p>
	<p>Defaults to <c>standard_io</c>, unless
	  parameter <seeerl marker="#file"><c>file</c></seeerl> is
	  given, in which case it defaults to <c>file</c>.</p>
      </item>
      <tag><marker id="file"/><c>file = </c><seetype marker="file#filename"><c>file:filename()</c></seetype></tag>
      <item>
	<p>This specifies the name of the log file when the handler is
	  of type <c>file</c>.</p>
	<p>The value is set when the handler is added, and it cannot
	  be changed in runtime.</p>
	<p>Defaults to the same name as the handler identity, in the
	  current directory.</p>
      </item>
      <tag><marker id="modes"/><c>modes = [</c><seetype marker="file#mode"><c>file:mode()</c></seetype><c>]</c></tag>
      <item>
	<p>This specifies the file modes to use when opening the log
	  file,
	  see <seemfa marker="file#open/2"><c>file:open/2</c></seemfa>.
	  If <c>modes</c> are not specified, the default list used
	  is <c>[raw,append,delayed_write]</c>. If <c>modes</c> are
	  specified, the list replaces the default modes list with the
	  following adjustments:</p>
	<list>
	  <item>
	    If <c>raw</c> is not found in the list, it is added.
	  </item>
	  <item>
	    If none of <c>write</c>, <c>append</c> or <c>exclusive</c> is
	    found in the list, <c>append</c> is added.</item>
	  <item>If none of <c>delayed_write</c>
	    or <c>{delayed_write,Size,Delay}</c> is found in the
	    list, <c>delayed_write</c> is added.</item>
	</list>
	<p>Log files are always UTF-8 encoded. The encoding cannot be
	  changed by setting the mode <c>{encoding,Encoding}</c>.</p>
	<p>The value is set when the handler is added, and it cannot
	  be changed in runtime.</p>
	<p>Defaults to <c>[raw,append,delayed_write]</c>.</p>
      </item>
      <tag><marker id="max_no_bytes"/><c>max_no_bytes = pos_integer() | infinity</c></tag>
      <item>
	<p>This parameter specifies if the log file should be rotated
	  or not. The value <c>infinity</c> means the log file will
	  grow indefinitely, while an integer value specifies at which
	  file size (bytes) the file is rotated.</p>
	<p>Defaults to <c>infinity</c>.</p>
      </item>
      <tag><marker id="max_no_files"/><c>max_no_files = non_neg_integer()</c></tag>
      <item>
	<p>This parameter specifies the number of rotated log file
	  archives to keep. This has meaning only
	  if <seeerl marker="#max_no_bytes"><c>max_no_bytes</c></seeerl>
	  is set to an integer value.</p>
	<p>The log archives are
	  named <c>FileName.0</c>, <c>FileName.1</c>,
	  ... <c>FileName.N</c>, where <c>FileName</c> is the name of
	  the current log file. <c>FileName.0</c> is the newest of the
	  archives. The maximum value for <c>N</c> is the value
	  of <c>max_no_files</c> minus 1.</p>
	<p>Notice that setting this value to <c>0</c> does not turn of
	  rotation. It only specifies that no archives are kept.</p>
	<p>Defaults to <c>0</c>.</p>
      </item>
      <tag><marker id="compress_on_rotate"/><c>compress_on_rotate = boolean()</c></tag>
      <item>
	<p>This parameter specifies if the rotated log file archives
	  shall be compressed or not. If set to <c>true</c>, all
	  archives are compressed with <c>gzip</c>, and renamed
	  to <c>FileName.N.gz</c></p>
	<p><c>compress_on_rotate</c> has no meaning if <seeerl
	marker="#max_no_bytes"><c>max_no_bytes</c></seeerl> has the
	value <c>infinity</c>.</p>
	<p>Defaults to <c>false</c>.</p>
      </item>
      <tag><marker id="file_check"/><c>file_check = non_neg_integer()</c></tag>
      <item>
	<p>When <c>logger_std_h</c> logs to a file, it reads the file
	  information of the log file prior to each write
	  operation. This is to make sure the file still exists and
	  has the same inode as when it was opened. This implies some
	  performance loss, but ensures that no log events are lost in
	  the case when the file has been removed or renamed by an
	  external actor.</p>
	<p>In order to allow minimizing the performance loss, the
	  <c>file_check</c> parameter can be set to a positive integer
	  value, <c>N</c>. The handler will then skip reading the file
	  information prior to writing, as long as no more
	  than <c>N</c> milliseconds have passed since it was last
	  read.</p>
	<p>Notice that the risk of loosing log events grows when
	  the <c>file_check</c> value grows.</p>
	<p>Defaults to 0.</p>
      </item>
      <tag><c>filesync_repeat_interval = pos_integer() | no_repeat</c></tag>
      <item>
	<p>This value, in milliseconds, specifies how often the handler does
	a file sync operation to write buffered data to disk. The handler attempts
	the operation repeatedly, but only performs a new sync if something has
	actually been logged.</p>
	<p>If <c>no_repeat</c> is set as value, the repeated file sync operation
	is disabled, and it is the operating system settings that determine
	how quickly or slowly data is written to disk. The user can also call
	the <seemfa marker="logger_std_h#filesync/1"><c>filesync/1</c></seemfa>
        function to perform a file sync.</p>
	<p>Defaults to <c>5000</c> milliseconds.</p>
      </item>
    </taglist>
    <p>Other configuration parameters exist, to be used for customizing
    the overload protection behaviour. The same parameters are used both in the
    standard handler and the disk_log handler, and are documented in the
    <seeguide marker="logger_chapter#overload_protection"><c>User's Guide</c>
    </seeguide>.</p>
    <p>Notice that if changing the configuration of the handler in
    runtime, the <c>type</c>, <c>file</c>, or <c>modes</c> parameters
    must not be modified.</p>
    <p>Example of adding a standard handler:</p>
    <code type="none">
logger:add_handler(my_standard_h, logger_std_h,
                   #{config => #{file => "./system_info.log",
                                 filesync_repeat_interval => 1000}}).
    </code>
    <p>To set the default handler, that starts initially with
    the Kernel application, to log to file instead of <c>standard_io</c>,
    change the Kernel default logger configuration. Example:</p>
    <code type="none">
erl -kernel logger '[{handler,default,logger_std_h,
                      #{config => #{file => "./log.log"}}}]'
    </code>
    <p>An example of how to replace the standard handler with a disk_log handler
    at startup is found in the
    <seeerl marker="logger_disk_log_h"><c>logger_disk_log_h</c></seeerl>
    manual.</p>
  </description>

  <funcs>

    <func>
      <name name="filesync" arity="1" clause_i="1" since="OTP 21.0"/>
      <fsummary>Writes buffered data to disk.</fsummary>
      <desc>
        <p>Write buffered data to disk.</p>
      </desc>
    </func>

  </funcs>

  <section>
    <title>See Also</title>
    <p><seeerl marker="logger"><c>logger(3)</c></seeerl>,
      <seeerl marker="logger_disk_log_h">
	<c>logger_disk_log_h(3)</c></seeerl></p>
  </section>
</erlref>


