Provided by: erlang-manpages_22.2.7+dfsg-1ubuntu0.5_all bug

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 formatted 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. Asynchronous 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.

       A  collection of open disk logs with the same name running on different nodes is said to be a distributed
       disk log if requests made to any of the logs are automatically made  to  the  other  logs  as  well.  The
       members  of  such a collection are called individual distributed disk logs, or just distributed disk logs
       if there is no risk of confusion. There is no order  between  the  members  of  such  a  collection.  For
       example,  logged  terms are not necessarily written to the node where the request was made before written
       to the other nodes. However, a few functions do not make requests to  all  members  of  distributed  disk
       logs, namely info/1, chunk/2,3, bchunk/2,3, chunk_step/3, and lclose/1,2.

       An  open  disk log that is not a distributed disk log is said to be a local disk log. A local disk log is
       only accessible from the node where the disk  log  process  runs,  whereas  a  distributed  disk  log  is
       accessible  from  all  nodes in the Erlang system, except for those nodes where a local disk log with the
       same name as the distributed disk log exists. All processes on nodes that  have  access  to  a  local  or
       distributed disk log can log items or otherwise change, inspect, or close the log.

       It  is not guaranteed that all log files of a distributed disk log contain the same log items. No attempt
       is made to synchronize the contents of the files. However, as long as at least one of the involved  nodes
       is alive at each time, all items are logged. When logging items to a distributed log, or otherwise trying
       to  change  the  log,  the  replies from individual logs are ignored. If all nodes are down, the disk log
       functions reply with a nonode error.

   Note:
       In some applications, it  can  be  unacceptable  that  replies  from  individual  logs  are  ignored.  An
       alternative  in  such  situations is to use many local disk logs instead of one distributed disk log, and
       implement the distribution without use of the disk_log module.

       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 direction only. Any process using a disk
       log  must  check  for  error  message  no_such_log  if  some  other  process truncates or reopens the log
       simultaneously.

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

       accessible_logs() -> {[LocalLog], [DistributedLog]}

              Types:

                 LocalLog = DistributedLog = log()

              Returns the names of the disk logs accessible on the current node. The first list  contains  local
              disk logs and the second list contains distributed disk logs.

       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 function 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 function 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 current 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, function 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 continuation, the atom start,  must  be
              provided.  If  a  disk  log  process is running on the current node, terms are read from that log.
              Otherwise, an individual distributed log on some other node is chosen, if such a log exists.

              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 missing, 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 continuation 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 continuation returned, points to  the  first
              log item in the new current file.

              If  atom  start  is specified as continuation, a disk log to read terms from is chosen. A local or
              distributed disk log on the current node is preferred to an individual  distributed  log  on  some
              other node.

              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 local or distributed 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 owners 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 message, 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()} |
                     {distributed, Dist :: local | [node()]} |
                     {head,
                      Head ::
                          none | {head, term()} | (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 the log. If a disk log process is running  on  the
              current  node,  that log is used as source of information, otherwise an individual distributed log
              on some other node is chosen, if such a log exists.

              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 function 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 functions block/1,2 and unblock/1.

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

                {distributed, Dist}:
                  If  the  log is local on the current node, Dist has the value local, otherwise all nodes where
                  the log is distributed are returned as a list.

              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 values 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 local log or an individual distributed log on the current node.

              lclose/2 closes an individual distributed log on the specified node if the node is not the current
              one.

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

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

       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. If the log is distributed, ok is returned, unless all nodes are down. Terms  are  written
              by  the  ordinary  write()  function of the operating system. 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  internally  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, Resaon :: 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 sublist 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() | dist_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()} |
                     {distributed, Nodes :: [node()]} |
                     {notify, boolean()} |
                     {head, Head :: dlog_head_opt()} |
                     {head_func, MFA :: {atom(), atom(), list()}} |
                     {quiet, boolean()} |
                     {mode, Mode :: dlog_mode()}
                 open_ret() = ret() | {error, open_error_rsn()}
                 ret() =
                     {ok, Log :: log()} |
                     {repaired,
                      Log :: log(),
                      {recovered, Rec :: integer() >= 0},
                      {badbytes, Bad :: integer() >= 0}}
                 dist_open_ret() =
                     {[{node(), ret()}], [{node(), {error, dist_error_rsn()}}]}
                 dist_error_rsn() = nodedown | 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 |
                     distributed | 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 integer. 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 truncated, 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.

                  When opening an existing wrap log, it is not necessary to supply a value for option Size,  but
                  any   supplied   value   must  equal  the  current  log  size,  otherwise  the  tuple  {error,
                  {size_mismatch, CurrentSize, NewSize}} is returned.

                {distributed, Nodes}:
                  This option can be used for adding members to a distributed disk log. Defaults  to  [],  which
                  means that the log is local on the current node.

                {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 previously 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 function 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  internal,
                  otherwise  a  sequence of bytes. 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 a sequence of bytes.

                {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 recoverable 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.  If  the  parameter  distributed  is  specified,  open/1 returns a list of
              successful replies and a list of erroneous replies. Each reply is tagged with the node name.

              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 created, 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.

              If a log with a specified name is local on some node, and one tries to open the log distributed on
              the same node, the tuple {error, {node_already_open, Log}} is returned. The same tuple is returned
              if the log is distributed on some node, and one tries to open the log locally on  the  same  node.
              Opening  individual distributed disk logs for the first time adds those logs to a (possibly empty)
              distributed disk log. The supplied option values  are  used  on  all  nodes  mentioned  by  option
              distributed.  Individual  distributed  logs know nothing about each other's option values, so each
              node can be given unique option values by creating a distributed log with many calls to open/1.

              A log file can be opened more than once by giving different values to option name or by using  the
              same  file  when distributing 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,Reason},[{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 argument 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,2  are  used  for  internally  formatted logs, and btruncate/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,Reason},[{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(3erl), pg2(3erl), wrap_log_reader(3erl)

Ericsson AB                                       kernel 6.5.1                                    disk_log(3erl)