Go to main content

man pages section 3: Extended Library Functions, Volume 1

Exit Print View

Updated: Wednesday, July 27, 2022
 
 

disk_log (3erl)

Name

disk_log - based term logging facility.

Synopsis

Please see following description for synopsis

Description

disk_log(3)                Erlang Module Definition                disk_log(3)



NAME
       disk_log - A disk-based term logging facility.

DESCRIPTION
       disk_log  is a disk-based term logger that enables efficient logging of
       items on files.

       Two types of logs are supported:

         halt logs:
           Appends items to a single file, which size can be  limited  by  the
           disk_log module.

         wrap logs:
           Uses  a  sequence  of wrap log files of limited size. As a wrap log
           file is filled up, further items are logged on to the next file  in
           the  sequence,  starting all over with the first file when the last
           file is filled up.

       For efficiency reasons, items are always written to files as binaries.

       Two formats of the log files are supported:

         internal format:
           Supports automatic repair of log files that are not properly closed
           and enables efficient reading of logged items in chunks using a set
           of functions defined in this module. This is the only way  to  read
           internally  formatted logs. An item logged to an internally format-
           ted log must not occupy more than 4 GB of disk space (the size must
           fit in 4 bytes).

         external format:
           Leaves it up to the user to read and interpret the logged data. The
           disk_log module cannot repair externally formatted logs.

       For each open disk log, one process handles requests made to  the  disk
       log.  This  process  is  created  when open/1 is called, provided there
       exists no process handling the disk log. A process that  opens  a  disk
       log can be an owner or an anonymous user of the disk log. Each owner is
       linked to the disk log process, and an owner can  close  the  disk  log
       either explicitly (by calling close/1 or lclose/1,2) or by terminating.

       Owners  can subscribe to notifications, messages of the form {disk_log,
       Node, Log, Info}, which are sent from the disk log process when certain
       events  occur,  see  the  functions and in particular the open/1 option
       notify. A log can have many owners, but a process cannot own a log more
       than  once.  However,  the same process can open the log as a user more
       than once.

       For a disk log process to close its file  properly  and  terminate,  it
       must  be  closed  by  its owners and once by some non-owner process for
       each time the log was used anonymously. The users are counted and there
       must not be any users left when the disk log process terminates.

       Items  can  be  logged  synchronously by using functions log/2, blog/2,
       log_terms/2, and blog_terms/2. For each of these functions, the  caller
       is put on hold until the items are logged (but not necessarily written,
       use sync/1 to ensure that). By adding an a to  each  of  the  mentioned
       function  names,  we get functions that log items asynchronously. Asyn-
       chronous functions do not wait for the disk log process  to  write  the
       items  to  the  file, but return the control to the caller more or less
       immediately.

       When  using  the  internal  format  for  logs,  use  functions   log/2,
       log_terms/2,  alog/2, and alog_terms/2. These functions log one or more
       Erlang terms. By  prefixing  each  of  the  functions  with  a  b  (for
       "binary"),  we  get the corresponding blog() functions for the external
       format. These functions log one or more chunks of bytes.  For  example,
       to   log   the   string   "hello"   in   ASCII   format,  you  can  use
       disk_log:blog(Log,        "hello"),        or        disk_log:blog(Log,
       list_to_binary("hello")). The two alternatives are equally efficient.

       The  blog()  functions  can also be used for internally formatted logs,
       but in this case they must be called  with  binaries  constructed  with
       calls  to  term_to_binary/1.  There  is  no check to ensure this, it is
       entirely the responsibility of  the  caller.  If  these  functions  are
       called  with  binaries  that  do  not  correspond  to Erlang terms, the
       chunk/2,3 and automatic repair functions fail. The corresponding  terms
       (not the binaries) are returned when chunk/2,3 is called.

       An  open  disk  log is only accessible from the node where the disk log
       process runs. All processes on the node where the disk log process runs
       can log items or otherwise change, inspect, or close the log.

       Errors are reported differently for asynchronous log attempts and other
       uses of the disk_log  module.  When  used  synchronously,  this  module
       replies  with  an  error  message, but when called asynchronously, this
       module does not know where to send the error message.  Instead,  owners
       subscribing to notifications receive an error_status message.

       The  disk_log module does not report errors to the error_logger module.
       It is up to the caller to decide whether to employ  the  error  logger.
       Function  format_error/1  can be used to produce readable messages from
       error replies. However, information events are sent to the error logger
       in  two  situations,  namely  when a log is repaired, or when a file is
       missing while reading chunks.

       Error message no_such_log means that the  specified  disk  log  is  not
       open. Nothing is said about whether the disk log files exist or not.

   Note:
       If  an  attempt  to  reopen or truncate a log fails (see reopen/2,3 and
       truncate/1,2) the disk log process terminates immediately.  Before  the
       process  terminates,  links  to  owners  and  blocking  processes  (see
       block/1,2) are removed. The effect is that the links work in one direc-
       tion  only.  Any  process using a disk log must check for error message
       no_such_log if some other process truncates or reopens the log simulta-
       neously.


DATA TYPES
       log() = term()

       dlog_size() =
           infinity |
           integer() >= 1 |
           {MaxNoBytes :: integer() >= 1, MaxNoFiles :: integer() >= 1}

       dlog_format() = external | internal

       dlog_head_opt() = none | term() | iodata()

       dlog_mode() = read_only | read_write

       dlog_type() = halt | wrap

       continuation()

              Chunk   continuation   returned  by  chunk/2,3,  bchunk/2,3,  or
              chunk_step/3.

       invalid_header() = term()

       file_error() = term()

EXPORTS
       all() -> [Log]

              Types:

                 Log = log()

              Returns the names of the disk logs  accessible  on  the  current
              node.

       accessible_logs() -> {[Log], []}

              Types:

                 Log = log()

              Returns  the  names  of  the disk logs accessible on the current
              node. The first list contains  the  logs.  The  second  list  is
              always  empty  (before  Erlang/OTP  24.0  it  used to contain so
              called distributed disk logs).

          Note:
              This function is deprecated. Use all/0 instead.


       alog(Log, Term) -> notify_ret()

       balog(Log, Bytes) -> notify_ret()

              Types:

                 Log = log()
                 Term = term()
                 Bytes = iodata()
                 notify_ret() = ok | {error, no_such_log}

              Asynchronously append an item to a disk log. alog/2 is used  for
              internally  formatted  logs and balog/2 for externally formatted
              logs. balog/2 can also be used for internally formatted logs  if
              the binary is constructed with a call to term_to_binary/1.

              Owners  subscribing  to notifications receive message read_only,
              blocked_log, or format_external if the item cannot be written on
              the  log,  and  possibly  one  of  the  messages  wrap, full, or
              error_status  if  an  item  is  written  on  the  log.   Message
              error_status is sent if something is wrong with the header func-
              tion or if a file error occurs.

       alog_terms(Log, TermList) -> notify_ret()

       balog_terms(Log, ByteList) -> notify_ret()

              Types:

                 Log = log()
                 TermList = [term()]
                 ByteList = [iodata()]
                 notify_ret() = ok | {error, no_such_log}

              Asynchronously  append  a  list  of  items  to   a   disk   log.
              alog_terms/2   is   used   for  internally  formatted  logs  and
              balog_terms/2 for externally formatted logs.  balog_terms/2  can
              also  be  used for internally formatted logs if the binaries are
              constructed with calls to term_to_binary/1.

              Owners subscribing to notifications receive  message  read_only,
              blocked_log,  or  format_external if the items cannot be written
              on the log, and possibly one or more of the messages wrap, full,
              and  error_status  if  items  are  written  on  the log. Message
              error_status is sent if something is wrong with the header func-
              tion or if a file error occurs.

       block(Log) -> ok | {error, block_error_rsn()}

       block(Log, QueueLogRecords) -> ok | {error, block_error_rsn()}

              Types:

                 Log = log()
                 QueueLogRecords = boolean()
                 block_error_rsn() = no_such_log | nonode | {blocked_log, log()}

              With  a  call  to  block/1,2  a  process can block a log. If the
              blocking process is not an owner of the log, a temporary link is
              created  between  the disk log process and the blocking process.
              The link ensures that the disk log is unblocked if the  blocking
              process terminates without first closing or unblocking the log.

              Any process can probe a blocked log with info/1 or close it with
              close/1. The blocking process can also use functions  chunk/2,3,
              bchunk/2,3,  chunk_step/3,  and unblock/1 without being affected
              by the block. Any other attempt than those mentioned so  far  to
              update  or read a blocked log suspends the calling process until
              the log is unblocked  or  returns  error  message  {blocked_log,
              Log},  depending on whether the value of QueueLogRecords is true
              or false. QueueLogRecords defaults to true,  which  is  used  by
              block/1.

       change_header(Log, Header) -> ok | {error, Reason}

              Types:

                 Log = log()
                 Header =
                     {head, dlog_head_opt()} |
                     {head_func, MFA :: {atom(), atom(), list()}}
                 Reason =
                     no_such_log | nonode |
                     {read_only_mode, Log} |
                     {blocked_log, Log} |
                     {badarg, head}

              Changes  the value of option head or head_func for an owner of a
              disk log.

       change_notify(Log, Owner, Notify) -> ok | {error, Reason}

              Types:

                 Log = log()
                 Owner = pid()
                 Notify = boolean()
                 Reason =
                     no_such_log | nonode |
                     {blocked_log, Log} |
                     {badarg, notify} |
                     {not_owner, Owner}

              Changes the value of option notify for an owner of a disk log.

       change_size(Log, Size) -> ok | {error, Reason}

              Types:

                 Log = log()
                 Size = dlog_size()
                 Reason =
                     no_such_log | nonode |
                     {read_only_mode, Log} |
                     {blocked_log, Log} |
                     {new_size_too_small, Log, CurrentSize :: integer() >=  1}
                 |
                     {badarg, size} |
                     {file_error, file:filename(), file_error()}

              Changes  the  size  of an open log. For a halt log, the size can
              always be increased, but it cannot  be  decreased  to  something
              less than the current file size.

              For a wrap log, both the size and the number of files can always
              be increased, as long as the number of  files  does  not  exceed
              65000.  If  the maximum number of files is decreased, the change
              is not valid until the current file is full and the log wraps to
              the next file. The redundant files are removed the next time the
              log wraps around, that is, starts to log to file number 1.

              As an example, assume that the old maximum number of files is 10
              and  that  the  new maximum number of files is 6. If the current
              file number is not greater than the new maximum number of files,
              files 7-10 are removed when file 6 is full and the log starts to
              write to file number 1 again. Otherwise, the files greater  than
              the  current file are removed when the current file is full (for
              example, if the current file is 8, files 9 and 10 are  removed).
              The  files  between the new maximum number of files and the cur-
              rent file (that is, files 7 and 8) are  removed  the  next  time
              file 6 is full.

              If  the  size  of the files is decreased, the change immediately
              affects the current log. It does not  change  the  size  of  log
              files already full until the next time they are used.

              If  the log size is decreased, for example, to save space, func-
              tion inc_wrap_file/1 can be used to force the log to wrap.

       chunk(Log, Continuation) -> chunk_ret()

       chunk(Log, Continuation, N) -> chunk_ret()

       bchunk(Log, Continuation) -> bchunk_ret()

       bchunk(Log, Continuation, N) -> bchunk_ret()

              Types:

                 Log = log()
                 Continuation = start | continuation()
                 N = integer() >= 1 | infinity
                 chunk_ret() =
                     {Continuation2 :: continuation(), Terms :: [term()]} |
                     {Continuation2 :: continuation(),
                      Terms :: [term()],
                      Badbytes :: integer() >= 0} |
                     eof |
                     {error, Reason :: chunk_error_rsn()}
                 bchunk_ret() =
                     {Continuation2 :: continuation(), Binaries :: [binary()]} |
                     {Continuation2 :: continuation(),
                      Binaries :: [binary()],
                      Badbytes :: integer() >= 0} |
                     eof |
                     {error, Reason :: chunk_error_rsn()}
                 chunk_error_rsn() =
                     no_such_log |
                     {format_external, log()} |
                     {blocked_log, log()} |
                     {badarg, continuation} |
                     {not_internal_wrap, log()} |
                     {corrupt_log_file, FileName :: file:filename()} |
                     {file_error, file:filename(), file_error()}

              Efficiently reads the terms that are appended to  an  internally
              formatted  log.  It  minimizes  disk  I/O by reading 64 kilobyte
              chunks from the file. Functions bchunk/2,3 return  the  binaries
              read  from  the  file,  they do not call binary_to_term(). Apart
              from that, they work just like chunk/2,3.

              The first time chunk() (or bchunk()) is called, an initial  con-
              tinuation, the atom start, must be provided.

              When  chunk/3  is called, N controls the maximum number of terms
              that are read from the log in each chunk. Defaults to  infinity,
              which  means  that  all  the  terms contained in the 64 kilobyte
              chunk are read. If less than N terms are returned, this does not
              necessarily mean that the end of the file is reached.

              chunk() returns a tuple {Continuation2, Terms}, where Terms is a
              list of terms found in the log.  Continuation2  is  yet  another
              continuation, which must be passed on to any subsequent calls to
              chunk(). With a series of calls to chunk(), all terms from a log
              can be extracted.

              chunk()  returns a tuple {Continuation2, Terms, Badbytes} if the
              log is opened in read-only mode and the read chunk  is  corrupt.
              Badbytes  is  the  number  of  bytes in the file found not to be
              Erlang terms in the chunk. Notice that the log is not  repaired.
              When trying to read chunks from a log opened in read-write mode,
              tuple {corrupt_log_file, FileName} is returned if the read chunk
              is corrupt.

              chunk()  returns  eof  when  the  end  of the log is reached, or
              {error, Reason} if an error occurs. If a wrap log file is  miss-
              ing, a message is output on the error log.

              When chunk/2,3 is used with wrap logs, the returned continuation
              might not be valid in the next call to chunk(). This is  because
              the log can wrap and delete the file into which the continuation
              points. To prevent this, the  log  can  be  blocked  during  the
              search.

       chunk_info(Continuation) -> InfoList | {error, Reason}

              Types:

                 Continuation = continuation()
                 InfoList = [{node, Node :: node()}, ...]
                 Reason = {no_continuation, Continuation}

              Returns the pair {node, Node}, describing the chunk continuation
              returned by chunk/2,3, bchunk/2,3, or chunk_step/3.

              Terms are read from the disk log running on Node.

       chunk_step(Log, Continuation, Step) ->
                     {ok, any()} | {error, Reason}

              Types:

                 Log = log()
                 Continuation = start | continuation()
                 Step = integer()
                 Reason =
                     no_such_log | end_of_log |
                     {format_external, Log} |
                     {blocked_log, Log} |
                     {badarg, continuation} |
                     {file_error, file:filename(), file_error()}

              Can be used with chunk/2,3 and bchunk/2,3 to search  through  an
              internally  formatted wrap log. It takes as argument a continua-
              tion as returned by chunk/2,3, bchunk/2,3, or chunk_step/3,  and
              steps forward (or backward) Step files in the wrap log. The con-
              tinuation returned, points to the first log item in the new cur-
              rent file.

              If  atom  start  is specified as continuation, the first file of
              the wrap log is chosen as the new current file.

              If the wrap log is not full because all files are not yet  used,
              {error,  end_of_log}  is  returned if trying to step outside the
              log.

       close(Log) -> ok | {error, close_error_rsn()}

              Types:

                 Log = log()
                 close_error_rsn() =
                     no_such_log | nonode |
                     {file_error, file:filename(), file_error()}

              Closes a disk log properly. An internally formatted log must  be
              closed  before  the Erlang system is stopped. Otherwise, the log
              is regarded as unclosed and the automatic  repair  procedure  is
              activated next time the log is opened.

              The disk log process is not terminated as long as there are own-
              ers or users of the log. All owners must close the log, possibly
              by  terminating. Also, any other process, not only the processes
              that have opened the log anonymously, can  decrement  the  users
              counter by closing the log. Attempts to close a log by a process
              that is not an owner are ignored if there are no users.

              If the log is blocked by the closing process, the  log  is  also
              unblocked.

       format_error(Error) -> io_lib:chars()

              Types:

                 Error = term()

              Given  the  error  returned by any function in this module, this
              function returns a descriptive string of the error  in  English.
              For  file  errors,  function  format_error/1  in  module file is
              called.

       inc_wrap_file(Log) -> ok | {error, inc_wrap_error_rsn()}

              Types:

                 Log = log()
                 inc_wrap_error_rsn() =
                     no_such_log | nonode |
                     {read_only_mode, log()} |
                     {blocked_log, log()} |
                     {halt_log, log()} |
                     {invalid_header, invalid_header()} |
                     {file_error, file:filename(), file_error()}
                 invalid_header() = term()

              Forces the internally formatted disk log to start logging to the
              next  log  file. It can be used, for example, with change_size/2
              to reduce the amount of disk space allocated by the disk log.

              Owners subscribing to notifications normally receive a wrap mes-
              sage, but if an error occurs with a reason tag of invalid_header
              or file_error, an error_status message is sent.

       info(Log) -> InfoList | {error, no_such_log}

              Types:

                 Log = log()
                 InfoList = [dlog_info()]
                 dlog_info() =
                     {name, Log :: log()} |
                     {file, File :: file:filename()} |
                     {type, Type :: dlog_type()} |
                     {format, Format :: dlog_format()} |
                     {size, Size :: dlog_size()} |
                     {mode, Mode :: dlog_mode()} |
                     {owners, [{pid(), Notify :: boolean()}]} |
                     {users, Users :: integer() >= 0} |
                     {status,
                      Status :: ok | {blocked, QueueLogRecords :: boolean()}} |
                     {node, Node :: node()} |
                     {head,
                      Head ::
                          none |
                          {head, binary()} |
                          (MFA :: {atom(), atom(), list()})} |
                     {no_written_items, NoWrittenItems :: integer() >= 0} |
                     {full, Full :: boolean} |
                     {no_current_bytes, integer() >= 0} |
                     {no_current_items, integer() >= 0} |
                     {no_items, integer() >= 0} |
                     {current_file, integer() >= 1} |
                     {no_overflows,
                      {SinceLogWasOpened :: integer() >= 0,
                       SinceLastInfo :: integer() >= 0}}

              Returns a list of {Tag, Value} pairs describing a log running on
              the node.

              The following pairs are returned for all logs:

                {name, Log}:
                  Log is the log name as specified by the open/1 option name.

                {file, File}:
                  For  halt  logs File is the filename, and for wrap logs File
                  is the base name.

                {type, Type}:
                  Type is the log type as specified by the open/1 option type.

                {format, Format}:
                  Format is the log format as specified by the  open/1  option
                  format.

                {size, Size}:
                  Size is the log size as specified by the open/1 option size,
                  or  the  size  set  by  change_size/2.  The  value  set   by
                  change_size/2 is reflected immediately.

                {mode, Mode}:
                  Mode is the log mode as specified by the open/1 option mode.

                {owners, [{pid(), Notify}]}:
                  Notify is the value set by the open/1 option notify or func-
                  tion change_notify/3 for the owners of the log.

                {users, Users}:
                  Users is the number of anonymous users of the log,  see  the
                  open/1 option linkto.

                {status, Status}:
                  Status  is  ok or {blocked, QueueLogRecords} as set by func-
                  tions block/1,2 and unblock/1.

                {node, Node}:
                  The information returned by the current invocation of  func-
                  tion info/1 is gathered from the disk log process running on
                  Node.

              The  following  pairs  are  returned  for  all  logs  opened  in
              read_write mode:

                {head, Head}:
                  Depending  on  the  value  of  the  open/1  options head and
                  head_func, or set by function change_header/2, the value  of
                  Head  is none (default), {head, H} (head option), or {M,F,A}
                  (head_func option).

                {no_written_items, NoWrittenItems}:
                  NoWrittenItems is the number of items  written  to  the  log
                  since the disk log process was created.

              The   following  pair  is  returned  for  halt  logs  opened  in
              read_write mode:

                {full, Full}:
                  Full is true or false depending on whether the halt  log  is
                  full or not.

              The  following  pairs  are  returned  for  wrap  logs  opened in
              read_write mode:

                {no_current_bytes, integer() >= 0}:
                  The number of bytes written to the current wrap log file.

                {no_current_items, integer() >= 0}:
                  The number of items written to the current  wrap  log  file,
                  header inclusive.

                {no_items, integer() >= 0}:
                  The total number of items in all wrap log files.

                {current_file, integer()}:
                  The  ordinal  for  the  current  wrap  log file in the range
                  1..MaxNoFiles, where MaxNoFiles is specified by  the  open/1
                  option size or set by change_size/2.

                {no_overflows, {SinceLogWasOpened, SinceLastInfo}}:
                  SinceLogWasOpened  (SinceLastInfo)  is the number of times a
                  wrap log file has been filled up and a new one is opened  or
                  inc_wrap_file/1  has been called since the disk log was last
                  opened (info/1 was last called). The first  time  info/2  is
                  called after a log was (re)opened or truncated, the two val-
                  ues are equal.

              Notice that functions chunk/2,3, bchunk/2,3, and chunk_step/3 do
              not affect any value returned by info/1.

       lclose(Log) -> ok | {error, lclose_error_rsn()}

       lclose(Log, Node) -> ok | {error, lclose_error_rsn()}

              Types:

                 Log = log()
                 Node = node()
                 lclose_error_rsn() =
                     no_such_log | {file_error, file:filename(), file_error()}

              lclose/1 closes a disk log on the current node.

              lclose/2  closes  a  disk log on the current node if Node is the
              current node.

              lclose(Log) is  equivalent  to  lclose(Log,  node()).  See  also
              close/1.

              If  no  log  with  the specified name exist on the current node,
              no_such_log is returned.

          Note:
              These functions are deprecated. Use close/1 instead.


       log(Log, Term) -> ok | {error, Reason :: log_error_rsn()}

       blog(Log, Bytes) -> ok | {error, Reason :: log_error_rsn()}

              Types:

                 Log = log()
                 Term = term()
                 Bytes = iodata()
                 log_error_rsn() =
                     no_such_log | nonode |
                     {read_only_mode, log()} |
                     {format_external, log()} |
                     {blocked_log, log()} |
                     {full, log()} |
                     {invalid_header, invalid_header()} |
                     {file_error, file:filename(), file_error()}

              Synchronously appends a term  to  a  disk  log.  Returns  ok  or
              {error,  Reason}  when  the  term  is written to disk. Terms are
              written by the ordinary write() function of the  operating  sys-
              tem.  Hence,  it  is  not guaranteed that the term is written to
              disk, it can linger in the operating system kernel for a  while.
              To ensure that the item is written to disk, function sync/1 must
              be called.

              log/2 is used for internally  formatted  logs,  and  blog/2  for
              externally  formatted  logs.  blog/2 can also be used for inter-
              nally formatted logs if the binary is constructed with a call to
              term_to_binary/1.

              Owners  subscribing  to  notifications  are notified of an error
              with  an  error_status  message  if  the  error  reason  tag  is
              invalid_header or file_error.

       log_terms(Log, TermList) ->
                    ok | {error, Reason :: log_error_rsn()}

       blog_terms(Log, BytesList) ->
                     ok | {error, Reason :: log_error_rsn()}

              Types:

                 Log = log()
                 TermList = [term()]
                 BytesList = [iodata()]
                 log_error_rsn() =
                     no_such_log | nonode |
                     {read_only_mode, log()} |
                     {format_external, log()} |
                     {blocked_log, log()} |
                     {full, log()} |
                     {invalid_header, invalid_header()} |
                     {file_error, file:filename(), file_error()}

              Synchronously  appends  a  list  of items to the log. It is more
              efficient to use these functions instead of functions log/2  and
              blog/2.  The  specified  list is split into as large sublists as
              possible (limited by the size of wrap log files), and each  sub-
              list is logged as one single item, which reduces the overhead.

              log_terms/2   is   used   for  internally  formatted  logs,  and
              blog_terms/2 for externally  formatted  logs.  blog_terms/2  can
              also  be  used for internally formatted logs if the binaries are
              constructed with calls to term_to_binary/1.

              Owners subscribing to notifications are  notified  of  an  error
              with  an  error_status  message  if  the  error  reason  tag  is
              invalid_header or file_error.

       open(ArgL) -> open_ret()

              Types:

                 ArgL = dlog_options()
                 dlog_options() = [dlog_option()]
                 dlog_option() =
                     {name, Log :: log()} |
                     {file, FileName :: file:filename()} |
                     {linkto, LinkTo :: none | pid()} |
                     {repair, Repair :: true | false | truncate} |
                     {type, Type :: dlog_type()} |
                     {format, Format :: dlog_format()} |
                     {size, Size :: dlog_size()} |
                     {notify, boolean()} |
                     {head, Head :: dlog_head_opt()} |
                     {head_func, MFA :: {atom(), atom(), list()}} |
                     {quiet, boolean()} |
                     {mode, Mode :: dlog_mode()}
                 open_ret() =
                     {ok, Log :: log()} |
                     {repaired,
                      Log :: log(),
                      {recovered, Rec :: integer() >= 0},
                      {badbytes, Bad :: integer() >= 0}} |
                     {error, open_error_rsn()}
                 open_error_rsn() =
                     no_such_log |
                     {badarg, term()} |
                     {size_mismatch,
                      CurrentSize :: dlog_size(),
                      NewSize :: dlog_size()} |
                     {arg_mismatch,
                      OptionName :: dlog_optattr(),
                      CurrentValue :: term(),
                      Value :: term()} |
                     {name_already_open, Log :: log()} |
                     {open_read_write, Log :: log()} |
                     {open_read_only, Log :: log()} |
                     {need_repair, Log :: log()} |
                     {not_a_log_file, FileName :: file:filename()} |
                     {invalid_index_file, FileName :: file:filename()} |
                     {invalid_header, invalid_header()} |
                     {file_error, file:filename(), file_error()} |
                     {node_already_open, Log :: log()}
                 dlog_optattr() =
                     name | file | linkto | repair | type | format | size |
                     notify | head | head_func | mode
                 dlog_size() =
                     infinity |
                     integer() >= 1 |
                     {MaxNoBytes :: integer() >= 1, MaxNoFiles :: integer() >= 1}

              Parameter ArgL is a list of the following options:

                {name, Log}:
                  Specifies the log name. This name must be  passed  on  as  a
                  parameter  in all subsequent logging operations. A name must
                  always be supplied.

                {file, FileName}:
                  Specifies the name of the file to be used for logged  terms.
                  If  this  value  is omitted and the log name is an atom or a
                  string, the filename defaults to lists:concat([Log, ".LOG"])
                  for halt logs.

                  For wrap logs, this is the base name of the files. Each file
                  in a wrap log is called <base_name>.N, where N is  an  inte-
                  ger. Each wrap log also has two files called <base_name>.idx
                  and <base_name>.siz.

                {linkto, LinkTo}:
                  If LinkTo is a pid, it becomes  an  owner  of  the  log.  If
                  LinkTo  is none, the log records that it is used anonymously
                  by some  process  by  incrementing  the  users  counter.  By
                  default, the process that calls open/1 owns the log.

                {repair, Repair}:
                  If  Repair  is  true,  the  current log file is repaired, if
                  needed. As the restoration is initiated, a message is output
                  on the error log. If false is specified, no automatic repair
                  is attempted. Instead, the tuple {error, {need_repair, Log}}
                  is  returned  if  an  attempt  is made to open a corrupt log
                  file. If truncate is specified, the log file  becomes  trun-
                  cated, creating an empty log. Defaults to true, which has no
                  effect on logs opened in read-only mode.

                {type, Type}:
                  The log type. Defaults to halt.

                {format, Format}:
                  Disk log format. Defaults to internal.

                {size, Size}:
                  Log size.

                  When a halt log has reached its maximum size,  all  attempts
                  to  log more items are rejected. Defaults to infinity, which
                  for halt implies that there is no maximum size.

                  For wrap logs, parameter Size can  be  a  pair  {MaxNoBytes,
                  MaxNoFiles} or infinity. In the latter case, if the files of
                  an existing wrap log with the same name can  be  found,  the
                  size  is read from the existing wrap log, otherwise an error
                  is returned.

                  Wrap logs write at most MaxNoBytes bytes on  each  file  and
                  use MaxNoFiles files before starting all over with the first
                  wrap log file. Regardless of MaxNoBytes, at least the header
                  (if  there is one) and one item are written on each wrap log
                  file before wrapping to the next file.

                  The first time an existing wrap log is opened, that is, when
                  the  disk  log  process  is created, the value of the option
                  size is allowed to differ from the current log size, and the
                  size of the disk log is changed as per change_size/2.

                  When  opening  an  existing wrap log, it is not necessary to
                  supply a value for option size, but if the  log  is  already
                  open,  that  is,  the  disk log process exists, the supplied
                  value must equal the current log size, otherwise  the  tuple
                  {error, {size_mismatch, CurrentSize, NewSize}} is returned.

            Note:
                Before  Erlang/OTP 24.0, the supplied value of option size was
                to be equal to the current log size when opening  an  existing
                wrap  log  for the first time, that is, when creating the disk
                log process.


                  When opening an  already  open  halt  log,  option  size  is
                  ignored.

                {notify, boolean()}:
                  If true, the log owners are notified when certain log events
                  occur. Defaults to false. The owners are  sent  one  of  the
                  following messages when an event occurs:

                  {disk_log, Node, Log, {wrap, NoLostItems}}:
                    Sent  when a wrap log has filled up one of its files and a
                    new file is opened. NoLostItems is the  number  of  previ-
                    ously logged items that were lost when truncating existing
                    files.

                  {disk_log, Node, Log, {truncated, NoLostItems}}:
                    Sent when a log is truncated or reopened.  For  halt  logs
                    NoLostItems  is  the  number  of  items written on the log
                    since the disk log process  was  created.  For  wrap  logs
                    NoLostItems is the number of items on all wrap log files.

                  {disk_log, Node, Log, {read_only, Items}}:
                    Sent  when  an  asynchronous  log attempt is made to a log
                    file opened in read-only mode. Items is the items from the
                    log attempt.

                  {disk_log, Node, Log, {blocked_log, Items}}:
                    Sent when an asynchronous log attempt is made to a blocked
                    log that does not queue log attempts. Items is  the  items
                    from the log attempt.

                  {disk_log, Node, Log, {format_external, Items}}:
                    Sent  when  function  alog/2  or  alog_terms/2 is used for
                    internally formatted logs. Items is the items from the log
                    attempt.

                  {disk_log, Node, Log, full}:
                    Sent  when  an  attempt  to  log items to a wrap log would
                    write more bytes than the limit set by option size.

                  {disk_log, Node, Log, {error_status, Status}}:
                    Sent when the error status changes. The  error  status  is
                    defined by the outcome of the last attempt to log items to
                    the log, or to truncate the log, or the last use of  func-
                    tion  sync/1, inc_wrap_file/1, or change_size/2. Status is
                    either ok or {error, Error}, the  former  is  the  initial
                    value.

                {head, Head}:
                  Specifies  a  header to be written first on the log file. If
                  the log is a wrap log, the item Head  is  written  first  in
                  each  new file. Head is to be a term if the format is inter-
                  nal, otherwise an iodata(). Defaults to  none,  which  means
                  that no header is written first on the file.

                {head_func, {M,F,A}}:
                  Specifies  a  function to be called each time a new log file
                  is opened. The call M:F(A) is assumed to return {ok,  Head}.
                  The item Head is written first in each file. Head is to be a
                  term if the format is internal, otherwise an iodata().

                {mode, Mode}:
                  Specifies if the log is to be opened in read-only  or  read-
                  write mode. Defaults to read_write.

                {quiet, Boolean}:
                  Specifies if messages will be sent to error_logger on recov-
                  erable errors with the log files. Defaults to false.

              open/1 returns {ok, Log} if the log file is successfully opened.
              If  the file is successfully repaired, the tuple {repaired, Log,
              {recovered, Rec}, {badbytes, Bad}} is returned, where Rec is the
              number  of  whole  Erlang terms found in the file and Bad is the
              number of bytes in the file that are non-Erlang terms.

              When a disk log is opened in read-write mode, any  existing  log
              file  is  checked for. If there is none, a new empty log is cre-
              ated, otherwise the existing file  is  opened  at  the  position
              after the last logged item, and the logging of items starts from
              there. If the format is internal and the existing  file  is  not
              recognized  as  an  internally  formatted  log,  a tuple {error,
              {not_a_log_file, FileName}} is returned.

              open/1 cannot be used for changing the values of options  of  an
              open  log.  When  there  are prior owners or users of a log, all
              option values except name, linkto, and notify are  only  checked
              against  the values supplied before as option values to function
              open/1,  change_header/2,  change_notify/3,  or   change_size/2.
              Thus,  none  of  the  options  except name is mandatory. If some
              specified value differs from the current value, a tuple  {error,
              {arg_mismatch, OptionName, CurrentValue, Value}} is returned.

          Note:
              If  an  owner  attempts to open a log as owner once again, it is
              acknowledged with the return value {ok, Log}, but the  state  of
              the disk log is not affected.


              A log file can be opened more than once by giving different val-
              ues to option name or by using the same file when opening a  log
              on  different  nodes. It is up to the user of module disk_log to
              ensure that not more than one disk log process has write  access
              to any file, otherwise the file can be corrupted.

              If  an  attempt to open a log file for the first time fails, the
              disk log process terminates with the EXIT message  {{failed,Rea-
              son},[{disk_log,open,1}]}.  The function returns {error, Reason}
              for all other errors.

       pid2name(Pid) -> {ok, Log} | undefined

              Types:

                 Pid = pid()
                 Log = log()

              Returns the log name given the pid of a disk log process on  the
              current  node,  or  undefined if the specified pid is not a disk
              log process.

              This function is meant to be used for debugging only.

       reopen(Log, File) -> ok | {error, reopen_error_rsn()}

       reopen(Log, File, Head) -> ok | {error, reopen_error_rsn()}

       breopen(Log, File, BHead) -> ok | {error, reopen_error_rsn()}

              Types:

                 Log = log()
                 File = file:filename()
                 Head = term()
                 BHead = iodata()
                 reopen_error_rsn() =
                     no_such_log | nonode |
                     {read_only_mode, log()} |
                     {blocked_log, log()} |
                     {same_file_name, log()} |
                     {invalid_index_file, file:filename()} |
                     {invalid_header, invalid_header()} |
                     {file_error, file:filename(), file_error()}

              Renames the log file to File and then recreates a new log  file.
              If  a  wrap  log  exists,  File  is used as the base name of the
              renamed files. By default the header given to open/1 is  written
              first  in  the  newly  opened  log file, but if argument Head or
              BHead is specified, this item is used instead. The header  argu-
              ment is used only once. Next time a wrap log file is opened, the
              header given to open/1 is used.

              reopen/2,3 are used for internally formatted logs, and breopen/3
              for externally formatted logs.

              Owners subscribing to notifications receive a truncate message.

              Upon  failure to reopen the log, the disk log process terminates
              with the EXIT  message  {{failed,Error},[{disk_log,Fun,Arity}]}.
              Other  processes  having  requests  queued  receive  the message
              {disk_log, Node, {error, disk_log_stopped}}.

       sync(Log) -> ok | {error, sync_error_rsn()}

              Types:

                 Log = log()
                 sync_error_rsn() =
                     no_such_log | nonode |
                     {read_only_mode, log()} |
                     {blocked_log, log()} |
                     {file_error, file:filename(), file_error()}

              Ensures that the contents of the log are written  to  the  disk.
              This is usually a rather expensive operation.

       truncate(Log) -> ok | {error, trunc_error_rsn()}

       truncate(Log, Head) -> ok | {error, trunc_error_rsn()}

       btruncate(Log, BHead) -> ok | {error, trunc_error_rsn()}

              Types:

                 Log = log()
                 Head = term()
                 BHead = iodata()
                 trunc_error_rsn() =
                     no_such_log | nonode |
                     {read_only_mode, log()} |
                     {blocked_log, log()} |
                     {invalid_header, invalid_header()} |
                     {file_error, file:filename(), file_error()}

              Removes  all items from a disk log. If argument Head or BHead is
              specified, this item is written first  in  the  newly  truncated
              log,  otherwise  the  header given to open/1 is used. The header
              argument is used only once. Next time a wrap log file is opened,
              the header given to open/1 is used.

              truncate/1  is used for both internally and externally formatted
              logs.

              truncate/2 is used for internally  formatted  logs,  and  btrun-
              cate/2 for externally formatted logs.

              Owners subscribing to notifications receive a truncate message.

              If  the  attempt to truncate the log fails, the disk log process
              terminates    with    the     EXIT     message     {{failed,Rea-
              son},[{disk_log,Fun,Arity}]}.  Other  processes  having requests
              queued   receive   the   message   {disk_log,   Node,    {error,
              disk_log_stopped}}.

       unblock(Log) -> ok | {error, unblock_error_rsn()}

              Types:

                 Log = log()
                 unblock_error_rsn() =
                     no_such_log | nonode |
                     {not_blocked, log()} |
                     {not_blocked_by_pid, log()}

              Unblocks  a  log.  A  log  can only be unblocked by the blocking
              process.

SEE ALSO
       file(3), wrap_log_reader(3)



Ericsson AB                       kernel 8.2                       disk_log(3)