1disk_log(3)                Erlang Module Definition                disk_log(3)
2
3
4

NAME

6       disk_log - A disk-based term logging facility.
7

DESCRIPTION

9       disk_log  is a disk-based term logger that enables efficient logging of
10       items on files.
11
12       Two types of logs are supported:
13
14         halt logs:
15           Appends items to a single file, which size can be  limited  by  the
16           disk_log module.
17
18         wrap logs:
19           Uses  a  sequence  of wrap log files of limited size. As a wrap log
20           file is filled up, further items are logged on to the next file  in
21           the  sequence,  starting all over with the first file when the last
22           file is filled up.
23
24       For efficiency reasons, items are always written to files as binaries.
25
26       Two formats of the log files are supported:
27
28         internal format:
29           Supports automatic repair of log files that are not properly closed
30           and enables efficient reading of logged items in chunks using a set
31           of functions defined in this module. This is the only way  to  read
32           internally  formatted logs. An item logged to an internally format‐
33           ted log must not occupy more than 4 GB of disk space (the size must
34           fit in 4 bytes).
35
36         external format:
37           Leaves it up to the user to read and interpret the logged data. The
38           disk_log module cannot repair externally formatted logs.
39
40       For each open disk log, one process handles requests made to  the  disk
41       log.  This process is created when open/1 is called, provided there ex‐
42       ists no process handling the disk log. A process that opens a disk  log
43       can  be  an  owner  or an anonymous user of the disk log. Each owner is
44       linked to the disk log process, and an owner can close the disk log ei‐
45       ther explicitly (by calling close/1 or lclose/1,2) or by terminating.
46
47       Owners  can subscribe to notifications, messages of the form {disk_log,
48       Node, Log, Info}, which are sent from the disk log process when certain
49       events occur, see the functions and in particular the open/1 option no‐
50       tify. A log can have many owners, but a process cannot own a  log  more
51       than  once.  However,  the same process can open the log as a user more
52       than once.
53
54       For a disk log process to close its file  properly  and  terminate,  it
55       must  be  closed  by  its owners and once by some non-owner process for
56       each time the log was used anonymously. The users are counted and there
57       must not be any users left when the disk log process terminates.
58
59       Items  can  be  logged  synchronously by using functions log/2, blog/2,
60       log_terms/2, and blog_terms/2. For each of these functions, the  caller
61       is put on hold until the items are logged (but not necessarily written,
62       use sync/1 to ensure that). By adding an a to  each  of  the  mentioned
63       function  names,  we get functions that log items asynchronously. Asyn‐
64       chronous functions do not wait for the disk log process  to  write  the
65       items  to  the  file, but return the control to the caller more or less
66       immediately.
67
68       When  using  the  internal  format  for  logs,  use  functions   log/2,
69       log_terms/2,  alog/2, and alog_terms/2. These functions log one or more
70       Erlang terms. By prefixing each of the functions with  a  b  (for  "bi‐
71       nary"), we get the corresponding blog() functions for the external for‐
72       mat. These functions log one or more chunks of bytes. For  example,  to
73       log  the string "hello" in ASCII format, you can use disk_log:blog(Log,
74       "hello"), or disk_log:blog(Log, list_to_binary("hello")). The  two  al‐
75       ternatives are equally efficient.
76
77       The  blog()  functions  can also be used for internally formatted logs,
78       but in this case they must be called  with  binaries  constructed  with
79       calls  to term_to_binary/1. There is no check to ensure this, it is en‐
80       tirely the responsibility of the caller. If these functions are  called
81       with binaries that do not correspond to Erlang terms, the chunk/2,3 and
82       automatic repair functions fail. The corresponding terms (not the bina‐
83       ries) are returned when chunk/2,3 is called.
84
85       An  open  disk  log is only accessible from the node where the disk log
86       process runs. All processes on the node where the disk log process runs
87       can log items or otherwise change, inspect, or close the log.
88
89       Errors are reported differently for asynchronous log attempts and other
90       uses of the disk_log  module.  When  used  synchronously,  this  module
91       replies  with  an  error  message, but when called asynchronously, this
92       module does not know where to send the error message.  Instead,  owners
93       subscribing to notifications receive an error_status message.
94
95       The  disk_log module does not report errors to the error_logger module.
96       It is up to the caller to decide whether to employ  the  error  logger.
97       Function  format_error/1  can be used to produce readable messages from
98       error replies. However, information events are sent to the error logger
99       in  two  situations,  namely  when a log is repaired, or when a file is
100       missing while reading chunks.
101
102       Error message no_such_log means that the  specified  disk  log  is  not
103       open. Nothing is said about whether the disk log files exist or not.
104
105   Note:
106       If  an  attempt  to  reopen or truncate a log fails (see reopen/2,3 and
107       truncate/1,2) the disk log process terminates immediately.  Before  the
108       process  terminates,  links  to  owners  and  blocking  processes  (see
109       block/1,2) are removed. The effect is that the links work in one direc‐
110       tion  only.  Any  process using a disk log must check for error message
111       no_such_log if some other process truncates or reopens the log simulta‐
112       neously.
113
114

DATA TYPES

116       log() = term()
117
118       dlog_size() =
119           infinity |
120           integer() >= 1 |
121           {MaxNoBytes :: integer() >= 1, MaxNoFiles :: integer() >= 1}
122
123       dlog_format() = external | internal
124
125       dlog_head_opt() = none | term() | iodata()
126
127       dlog_mode() = read_only | read_write
128
129       dlog_type() = halt | wrap
130
131       continuation()
132
133              Chunk   continuation   returned  by  chunk/2,3,  bchunk/2,3,  or
134              chunk_step/3.
135
136       invalid_header() = term()
137
138       file_error() = term()
139

EXPORTS

141       all() -> [Log]
142
143              Types:
144
145                 Log = log()
146
147              Returns the names of the disk logs  accessible  on  the  current
148              node.
149
150       accessible_logs() -> {[Log], []}
151
152              Types:
153
154                 Log = log()
155
156              Returns  the  names  of  the disk logs accessible on the current
157              node. The first list contains the logs. The second list  is  al‐
158              ways  empty (before Erlang/OTP 24.0 it used to contain so called
159              distributed disk logs).
160
161          Note:
162              This function is deprecated. Use all/0 instead.
163
164
165       alog(Log, Term) -> notify_ret()
166
167       balog(Log, Bytes) -> notify_ret()
168
169              Types:
170
171                 Log = log()
172                 Term = term()
173                 Bytes = iodata()
174                 notify_ret() = ok | {error, no_such_log}
175
176              Asynchronously append an item to a disk log. alog/2 is used  for
177              internally  formatted  logs and balog/2 for externally formatted
178              logs. balog/2 can also be used for internally formatted logs  if
179              the binary is constructed with a call to term_to_binary/1.
180
181              Owners  subscribing  to notifications receive message read_only,
182              blocked_log, or format_external if the item cannot be written on
183              the  log,  and  possibly  one of the messages wrap, full, or er‐
184              ror_status if an item is written on the log. Message  error_sta‐
185              tus is sent if something is wrong with the header function or if
186              a file error occurs.
187
188       alog_terms(Log, TermList) -> notify_ret()
189
190       balog_terms(Log, ByteList) -> notify_ret()
191
192              Types:
193
194                 Log = log()
195                 TermList = [term()]
196                 ByteList = [iodata()]
197                 notify_ret() = ok | {error, no_such_log}
198
199              Asynchronously  append  a  list  of  items  to   a   disk   log.
200              alog_terms/2  is  used  for  internally  formatted  logs and ba‐
201              log_terms/2 for externally  formatted  logs.  balog_terms/2  can
202              also  be  used for internally formatted logs if the binaries are
203              constructed with calls to term_to_binary/1.
204
205              Owners subscribing to notifications receive  message  read_only,
206              blocked_log,  or  format_external if the items cannot be written
207              on the log, and possibly one or more of the messages wrap, full,
208              and  error_status  if  items are written on the log. Message er‐
209              ror_status is sent if something is wrong with the  header  func‐
210              tion or if a file error occurs.
211
212       block(Log) -> ok | {error, block_error_rsn()}
213
214       block(Log, QueueLogRecords) -> ok | {error, block_error_rsn()}
215
216              Types:
217
218                 Log = log()
219                 QueueLogRecords = boolean()
220                 block_error_rsn() = no_such_log | nonode | {blocked_log, log()}
221
222              With  a  call  to  block/1,2  a  process can block a log. If the
223              blocking process is not an owner of the log, a temporary link is
224              created  between  the disk log process and the blocking process.
225              The link ensures that the disk log is unblocked if the  blocking
226              process terminates without first closing or unblocking the log.
227
228              Any process can probe a blocked log with info/1 or close it with
229              close/1. The blocking process can also use functions  chunk/2,3,
230              bchunk/2,3,  chunk_step/3,  and unblock/1 without being affected
231              by the block. Any other attempt than those mentioned so  far  to
232              update  or read a blocked log suspends the calling process until
233              the log is unblocked  or  returns  error  message  {blocked_log,
234              Log},  depending on whether the value of QueueLogRecords is true
235              or false. QueueLogRecords defaults to true,  which  is  used  by
236              block/1.
237
238       change_header(Log, Header) -> ok | {error, Reason}
239
240              Types:
241
242                 Log = log()
243                 Header =
244                     {head, dlog_head_opt()} |
245                     {head_func, MFA :: {atom(), atom(), list()}}
246                 Reason =
247                     no_such_log | nonode |
248                     {read_only_mode, Log} |
249                     {blocked_log, Log} |
250                     {badarg, head}
251
252              Changes  the value of option head or head_func for an owner of a
253              disk log.
254
255       change_notify(Log, Owner, Notify) -> ok | {error, Reason}
256
257              Types:
258
259                 Log = log()
260                 Owner = pid()
261                 Notify = boolean()
262                 Reason =
263                     no_such_log | nonode |
264                     {blocked_log, Log} |
265                     {badarg, notify} |
266                     {not_owner, Owner}
267
268              Changes the value of option notify for an owner of a disk log.
269
270       change_size(Log, Size) -> ok | {error, Reason}
271
272              Types:
273
274                 Log = log()
275                 Size = dlog_size()
276                 Reason =
277                     no_such_log | nonode |
278                     {read_only_mode, Log} |
279                     {blocked_log, Log} |
280                     {new_size_too_small, Log, CurrentSize :: integer() >=  1}
281                 |
282                     {badarg, size} |
283                     {file_error, file:filename(), file_error()}
284
285              Changes  the  size  of an open log. For a halt log, the size can
286              always be increased, but it cannot  be  decreased  to  something
287              less than the current file size.
288
289              For a wrap log, both the size and the number of files can always
290              be increased, as long as the number of  files  does  not  exceed
291              65000.  If  the maximum number of files is decreased, the change
292              is not valid until the current file is full and the log wraps to
293              the next file. The redundant files are removed the next time the
294              log wraps around, that is, starts to log to file number 1.
295
296              As an example, assume that the old maximum number of files is 10
297              and  that  the  new maximum number of files is 6. If the current
298              file number is not greater than the new maximum number of files,
299              files 7-10 are removed when file 6 is full and the log starts to
300              write to file number 1 again. Otherwise, the files greater  than
301              the  current file are removed when the current file is full (for
302              example, if the current file is 8, files 9 and 10 are  removed).
303              The  files  between the new maximum number of files and the cur‐
304              rent file (that is, files 7 and 8) are  removed  the  next  time
305              file 6 is full.
306
307              If  the  size  of the files is decreased, the change immediately
308              affects the current log. It does not  change  the  size  of  log
309              files already full until the next time they are used.
310
311              If  the log size is decreased, for example, to save space, func‐
312              tion inc_wrap_file/1 can be used to force the log to wrap.
313
314       chunk(Log, Continuation) -> chunk_ret()
315
316       chunk(Log, Continuation, N) -> chunk_ret()
317
318       bchunk(Log, Continuation) -> bchunk_ret()
319
320       bchunk(Log, Continuation, N) -> bchunk_ret()
321
322              Types:
323
324                 Log = log()
325                 Continuation = start | continuation()
326                 N = integer() >= 1 | infinity
327                 chunk_ret() =
328                     {Continuation2 :: continuation(), Terms :: [term()]} |
329                     {Continuation2 :: continuation(),
330                      Terms :: [term()],
331                      Badbytes :: integer() >= 0} |
332                     eof |
333                     {error, Reason :: chunk_error_rsn()}
334                 bchunk_ret() =
335                     {Continuation2 :: continuation(), Binaries :: [binary()]} |
336                     {Continuation2 :: continuation(),
337                      Binaries :: [binary()],
338                      Badbytes :: integer() >= 0} |
339                     eof |
340                     {error, Reason :: chunk_error_rsn()}
341                 chunk_error_rsn() =
342                     no_such_log |
343                     {format_external, log()} |
344                     {blocked_log, log()} |
345                     {badarg, continuation} |
346                     {not_internal_wrap, log()} |
347                     {corrupt_log_file, FileName :: file:filename()} |
348                     {file_error, file:filename(), file_error()}
349
350              Efficiently reads the terms that are appended to  an  internally
351              formatted  log.  It  minimizes  disk  I/O by reading 64 kilobyte
352              chunks from the file. Functions bchunk/2,3 return  the  binaries
353              read  from  the  file,  they do not call binary_to_term(). Apart
354              from that, they work just like chunk/2,3.
355
356              The first time chunk() (or bchunk()) is called, an initial  con‐
357              tinuation, the atom start, must be provided.
358
359              When  chunk/3  is called, N controls the maximum number of terms
360              that are read from the log in each chunk. Defaults to  infinity,
361              which  means  that  all  the  terms contained in the 64 kilobyte
362              chunk are read. If less than N terms are returned, this does not
363              necessarily mean that the end of the file is reached.
364
365              chunk() returns a tuple {Continuation2, Terms}, where Terms is a
366              list of terms found in the log.  Continuation2  is  yet  another
367              continuation, which must be passed on to any subsequent calls to
368              chunk(). With a series of calls to chunk(), all terms from a log
369              can be extracted.
370
371              chunk()  returns a tuple {Continuation2, Terms, Badbytes} if the
372              log is opened in read-only mode and the read chunk  is  corrupt.
373              Badbytes  is the number of bytes in the file found not to be Er‐
374              lang terms in the chunk. Notice that the log  is  not  repaired.
375              When trying to read chunks from a log opened in read-write mode,
376              tuple {corrupt_log_file, FileName} is returned if the read chunk
377              is corrupt.
378
379              chunk()  returns eof when the end of the log is reached, or {er‐
380              ror, Reason} if an error occurs. If a wrap log file is  missing,
381              a message is output on the error log.
382
383              When chunk/2,3 is used with wrap logs, the returned continuation
384              might not be valid in the next call to chunk(). This is  because
385              the log can wrap and delete the file into which the continuation
386              points. To prevent this, the  log  can  be  blocked  during  the
387              search.
388
389       chunk_info(Continuation) -> InfoList | {error, Reason}
390
391              Types:
392
393                 Continuation = continuation()
394                 InfoList = [{node, Node :: node()}, ...]
395                 Reason = {no_continuation, Continuation}
396
397              Returns the pair {node, Node}, describing the chunk continuation
398              returned by chunk/2,3, bchunk/2,3, or chunk_step/3.
399
400              Terms are read from the disk log running on Node.
401
402       chunk_step(Log, Continuation, Step) ->
403                     {ok, any()} | {error, Reason}
404
405              Types:
406
407                 Log = log()
408                 Continuation = start | continuation()
409                 Step = integer()
410                 Reason =
411                     no_such_log | end_of_log |
412                     {format_external, Log} |
413                     {blocked_log, Log} |
414                     {badarg, continuation} |
415                     {file_error, file:filename(), file_error()}
416
417              Can be used with chunk/2,3 and bchunk/2,3 to search  through  an
418              internally  formatted wrap log. It takes as argument a continua‐
419              tion as returned by chunk/2,3, bchunk/2,3, or chunk_step/3,  and
420              steps forward (or backward) Step files in the wrap log. The con‐
421              tinuation returned, points to the first log item in the new cur‐
422              rent file.
423
424              If  atom  start  is specified as continuation, the first file of
425              the wrap log is chosen as the new current file.
426
427              If the wrap log is not full because all files are not yet  used,
428              {error,  end_of_log}  is  returned if trying to step outside the
429              log.
430
431       close(Log) -> ok | {error, close_error_rsn()}
432
433              Types:
434
435                 Log = log()
436                 close_error_rsn() =
437                     no_such_log | nonode |
438                     {file_error, file:filename(), file_error()}
439
440              Closes a disk log properly. An internally formatted log must  be
441              closed  before  the Erlang system is stopped. Otherwise, the log
442              is regarded as unclosed and the automatic  repair  procedure  is
443              activated next time the log is opened.
444
445              The disk log process is not terminated as long as there are own‐
446              ers or users of the log. All owners must close the log, possibly
447              by  terminating. Also, any other process, not only the processes
448              that have opened the log anonymously, can  decrement  the  users
449              counter by closing the log. Attempts to close a log by a process
450              that is not an owner are ignored if there are no users.
451
452              If the log is blocked by the closing process, the  log  is  also
453              unblocked.
454
455       format_error(Error) -> io_lib:chars()
456
457              Types:
458
459                 Error = term()
460
461              Given  the  error  returned by any function in this module, this
462              function returns a descriptive string of the error  in  English.
463              For  file  errors,  function  format_error/1  in  module file is
464              called.
465
466       inc_wrap_file(Log) -> ok | {error, inc_wrap_error_rsn()}
467
468              Types:
469
470                 Log = log()
471                 inc_wrap_error_rsn() =
472                     no_such_log | nonode |
473                     {read_only_mode, log()} |
474                     {blocked_log, log()} |
475                     {halt_log, log()} |
476                     {invalid_header, invalid_header()} |
477                     {file_error, file:filename(), file_error()}
478                 invalid_header() = term()
479
480              Forces the internally formatted disk log to start logging to the
481              next  log  file. It can be used, for example, with change_size/2
482              to reduce the amount of disk space allocated by the disk log.
483
484              Owners subscribing to notifications normally receive a wrap mes‐
485              sage, but if an error occurs with a reason tag of invalid_header
486              or file_error, an error_status message is sent.
487
488       info(Log) -> InfoList | {error, no_such_log}
489
490              Types:
491
492                 Log = log()
493                 InfoList = [dlog_info()]
494                 dlog_info() =
495                     {name, Log :: log()} |
496                     {file, File :: file:filename()} |
497                     {type, Type :: dlog_type()} |
498                     {format, Format :: dlog_format()} |
499                     {size, Size :: dlog_size()} |
500                     {mode, Mode :: dlog_mode()} |
501                     {owners, [{pid(), Notify :: boolean()}]} |
502                     {users, Users :: integer() >= 0} |
503                     {status,
504                      Status :: ok | {blocked, QueueLogRecords :: boolean()}} |
505                     {node, Node :: node()} |
506                     {head,
507                      Head ::
508                          none |
509                          {head, binary()} |
510                          (MFA :: {atom(), atom(), list()})} |
511                     {no_written_items, NoWrittenItems :: integer() >= 0} |
512                     {full, Full :: boolean} |
513                     {no_current_bytes, integer() >= 0} |
514                     {no_current_items, integer() >= 0} |
515                     {no_items, integer() >= 0} |
516                     {current_file, integer() >= 1} |
517                     {no_overflows,
518                      {SinceLogWasOpened :: integer() >= 0,
519                       SinceLastInfo :: integer() >= 0}}
520
521              Returns a list of {Tag, Value} pairs describing a log running on
522              the node.
523
524              The following pairs are returned for all logs:
525
526                {name, Log}:
527                  Log is the log name as specified by the open/1 option name.
528
529                {file, File}:
530                  For  halt  logs File is the filename, and for wrap logs File
531                  is the base name.
532
533                {type, Type}:
534                  Type is the log type as specified by the open/1 option type.
535
536                {format, Format}:
537                  Format is the log format as specified by the  open/1  option
538                  format.
539
540                {size, Size}:
541                  Size is the log size as specified by the open/1 option size,
542                  or  the  size  set  by  change_size/2.  The  value  set   by
543                  change_size/2 is reflected immediately.
544
545                {mode, Mode}:
546                  Mode is the log mode as specified by the open/1 option mode.
547
548                {owners, [{pid(), Notify}]}:
549                  Notify is the value set by the open/1 option notify or func‐
550                  tion change_notify/3 for the owners of the log.
551
552                {users, Users}:
553                  Users is the number of anonymous users of the log,  see  the
554                  open/1 option linkto.
555
556                {status, Status}:
557                  Status  is  ok or {blocked, QueueLogRecords} as set by func‐
558                  tions block/1,2 and unblock/1.
559
560                {node, Node}:
561                  The information returned by the current invocation of  func‐
562                  tion info/1 is gathered from the disk log process running on
563                  Node.
564
565              The  following  pairs  are  returned  for  all  logs  opened  in
566              read_write mode:
567
568                {head, Head}:
569                  Depending  on  the  value  of  the  open/1  options head and
570                  head_func, or set by function change_header/2, the value  of
571                  Head  is none (default), {head, H} (head option), or {M,F,A}
572                  (head_func option).
573
574                {no_written_items, NoWrittenItems}:
575                  NoWrittenItems is the number of items  written  to  the  log
576                  since the disk log process was created.
577
578              The   following  pair  is  returned  for  halt  logs  opened  in
579              read_write mode:
580
581                {full, Full}:
582                  Full is true or false depending on whether the halt  log  is
583                  full or not.
584
585              The  following  pairs  are  returned  for  wrap  logs  opened in
586              read_write mode:
587
588                {no_current_bytes, integer() >= 0}:
589                  The number of bytes written to the current wrap log file.
590
591                {no_current_items, integer() >= 0}:
592                  The number of items written to the current  wrap  log  file,
593                  header inclusive.
594
595                {no_items, integer() >= 0}:
596                  The total number of items in all wrap log files.
597
598                {current_file, integer()}:
599                  The  ordinal  for  the  current  wrap  log file in the range
600                  1..MaxNoFiles, where MaxNoFiles is specified by  the  open/1
601                  option size or set by change_size/2.
602
603                {no_overflows, {SinceLogWasOpened, SinceLastInfo}}:
604                  SinceLogWasOpened  (SinceLastInfo)  is the number of times a
605                  wrap log file has been filled up and a new one is opened  or
606                  inc_wrap_file/1  has been called since the disk log was last
607                  opened (info/1 was last called). The first  time  info/2  is
608                  called after a log was (re)opened or truncated, the two val‐
609                  ues are equal.
610
611              Notice that functions chunk/2,3, bchunk/2,3, and chunk_step/3 do
612              not affect any value returned by info/1.
613
614       lclose(Log) -> ok | {error, lclose_error_rsn()}
615
616       lclose(Log, Node) -> ok | {error, lclose_error_rsn()}
617
618              Types:
619
620                 Log = log()
621                 Node = node()
622                 lclose_error_rsn() =
623                     no_such_log | {file_error, file:filename(), file_error()}
624
625              lclose/1 closes a disk log on the current node.
626
627              lclose/2  closes  a  disk log on the current node if Node is the
628              current node.
629
630              lclose(Log) is  equivalent  to  lclose(Log,  node()).  See  also
631              close/1.
632
633              If  no  log  with  the specified name exist on the current node,
634              no_such_log is returned.
635
636          Note:
637              These functions are deprecated. Use close/1 instead.
638
639
640       log(Log, Term) -> ok | {error, Reason :: log_error_rsn()}
641
642       blog(Log, Bytes) -> ok | {error, Reason :: log_error_rsn()}
643
644              Types:
645
646                 Log = log()
647                 Term = term()
648                 Bytes = iodata()
649                 log_error_rsn() =
650                     no_such_log | nonode |
651                     {read_only_mode, log()} |
652                     {format_external, log()} |
653                     {blocked_log, log()} |
654                     {full, log()} |
655                     {invalid_header, invalid_header()} |
656                     {file_error, file:filename(), file_error()}
657
658              Synchronously appends a term to a disk log. Returns ok  or  {er‐
659              ror, Reason} when the term is written to disk. Terms are written
660              by the ordinary write() function of the operating system. Hence,
661              it  is  not  guaranteed that the term is written to disk, it can
662              linger in the operating system kernel for  a  while.  To  ensure
663              that  the  item  is  written  to  disk,  function sync/1 must be
664              called.
665
666              log/2 is used for internally formatted logs, and blog/2 for  ex‐
667              ternally  formatted logs. blog/2 can also be used for internally
668              formatted logs if the binary  is  constructed  with  a  call  to
669              term_to_binary/1.
670
671              Owners  subscribing  to  notifications  are notified of an error
672              with an error_status message if the  error  reason  tag  is  in‐
673              valid_header or file_error.
674
675       log_terms(Log, TermList) ->
676                    ok | {error, Reason :: log_error_rsn()}
677
678       blog_terms(Log, BytesList) ->
679                     ok | {error, Reason :: log_error_rsn()}
680
681              Types:
682
683                 Log = log()
684                 TermList = [term()]
685                 BytesList = [iodata()]
686                 log_error_rsn() =
687                     no_such_log | nonode |
688                     {read_only_mode, log()} |
689                     {format_external, log()} |
690                     {blocked_log, log()} |
691                     {full, log()} |
692                     {invalid_header, invalid_header()} |
693                     {file_error, file:filename(), file_error()}
694
695              Synchronously appends a list of items to the log. It is more ef‐
696              ficient to use these functions instead of  functions  log/2  and
697              blog/2.  The  specified  list is split into as large sublists as
698              possible (limited by the size of wrap log files), and each  sub‐
699              list is logged as one single item, which reduces the overhead.
700
701              log_terms/2   is   used   for  internally  formatted  logs,  and
702              blog_terms/2 for externally  formatted  logs.  blog_terms/2  can
703              also  be  used for internally formatted logs if the binaries are
704              constructed with calls to term_to_binary/1.
705
706              Owners subscribing to notifications are  notified  of  an  error
707              with  an  error_status  message  if  the error reason tag is in‐
708              valid_header or file_error.
709
710       open(ArgL) -> open_ret()
711
712              Types:
713
714                 ArgL = dlog_options()
715                 dlog_options() = [dlog_option()]
716                 dlog_option() =
717                     {name, Log :: log()} |
718                     {file, FileName :: file:filename()} |
719                     {linkto, LinkTo :: none | pid()} |
720                     {repair, Repair :: true | false | truncate} |
721                     {type, Type :: dlog_type()} |
722                     {format, Format :: dlog_format()} |
723                     {size, Size :: dlog_size()} |
724                     {notify, boolean()} |
725                     {head, Head :: dlog_head_opt()} |
726                     {head_func, MFA :: {atom(), atom(), list()}} |
727                     {quiet, boolean()} |
728                     {mode, Mode :: dlog_mode()}
729                 open_ret() =
730                     {ok, Log :: log()} |
731                     {repaired,
732                      Log :: log(),
733                      {recovered, Rec :: integer() >= 0},
734                      {badbytes, Bad :: integer() >= 0}} |
735                     {error, open_error_rsn()}
736                 open_error_rsn() =
737                     no_such_log |
738                     {badarg, term()} |
739                     {size_mismatch,
740                      CurrentSize :: dlog_size(),
741                      NewSize :: dlog_size()} |
742                     {arg_mismatch,
743                      OptionName :: dlog_optattr(),
744                      CurrentValue :: term(),
745                      Value :: term()} |
746                     {name_already_open, Log :: log()} |
747                     {open_read_write, Log :: log()} |
748                     {open_read_only, Log :: log()} |
749                     {need_repair, Log :: log()} |
750                     {not_a_log_file, FileName :: file:filename()} |
751                     {invalid_index_file, FileName :: file:filename()} |
752                     {invalid_header, invalid_header()} |
753                     {file_error, file:filename(), file_error()} |
754                     {node_already_open, Log :: log()}
755                 dlog_optattr() =
756                     name | file | linkto | repair | type | format | size |
757                     notify | head | head_func | mode
758                 dlog_size() =
759                     infinity |
760                     integer() >= 1 |
761                     {MaxNoBytes :: integer() >= 1, MaxNoFiles :: integer() >= 1}
762
763              Parameter ArgL is a list of the following options:
764
765                {name, Log}:
766                  Specifies the log name. This name must be passed on as a pa‐
767                  rameter  in  all  subsequent logging operations. A name must
768                  always be supplied.
769
770                {file, FileName}:
771                  Specifies the name of the file to be used for logged  terms.
772                  If  this  value  is omitted and the log name is an atom or a
773                  string, the filename defaults to lists:concat([Log, ".LOG"])
774                  for halt logs.
775
776                  For wrap logs, this is the base name of the files. Each file
777                  in a wrap log is called <base_name>.N, where N is  an  inte‐
778                  ger. Each wrap log also has two files called <base_name>.idx
779                  and <base_name>.siz.
780
781                {linkto, LinkTo}:
782                  If LinkTo is a pid, it becomes  an  owner  of  the  log.  If
783                  LinkTo  is none, the log records that it is used anonymously
784                  by some process by incrementing the users  counter.  By  de‐
785                  fault, the process that calls open/1 owns the log.
786
787                {repair, Repair}:
788                  If  Repair  is  true,  the  current log file is repaired, if
789                  needed. As the restoration is initiated, a message is output
790                  on the error log. If false is specified, no automatic repair
791                  is attempted. Instead, the tuple {error, {need_repair, Log}}
792                  is  returned  if  an  attempt  is made to open a corrupt log
793                  file. If truncate is specified, the log file  becomes  trun‐
794                  cated, creating an empty log. Defaults to true, which has no
795                  effect on logs opened in read-only mode.
796
797                {type, Type}:
798                  The log type. Defaults to halt.
799
800                {format, Format}:
801                  Disk log format. Defaults to internal.
802
803                {size, Size}:
804                  Log size.
805
806                  When a halt log has reached its maximum size,  all  attempts
807                  to  log more items are rejected. Defaults to infinity, which
808                  for halt implies that there is no maximum size.
809
810                  For wrap logs, parameter Size can  be  a  pair  {MaxNoBytes,
811                  MaxNoFiles} or infinity. In the latter case, if the files of
812                  an existing wrap log with the same name can  be  found,  the
813                  size  is read from the existing wrap log, otherwise an error
814                  is returned.
815
816                  Wrap logs write at most MaxNoBytes bytes on  each  file  and
817                  use MaxNoFiles files before starting all over with the first
818                  wrap log file. Regardless of MaxNoBytes, at least the header
819                  (if  there is one) and one item are written on each wrap log
820                  file before wrapping to the next file.
821
822                  The first time an existing wrap log is opened, that is, when
823                  the  disk  log  process  is created, the value of the option
824                  size is allowed to differ from the current log size, and the
825                  size of the disk log is changed as per change_size/2.
826
827                  When  opening  an  existing wrap log, it is not necessary to
828                  supply a value for option size, but if the  log  is  already
829                  open,  that  is,  the  disk log process exists, the supplied
830                  value must equal the current log size, otherwise  the  tuple
831                  {error, {size_mismatch, CurrentSize, NewSize}} is returned.
832
833            Note:
834                Before  Erlang/OTP 24.0, the supplied value of option size was
835                to be equal to the current log size when opening  an  existing
836                wrap  log  for the first time, that is, when creating the disk
837                log process.
838
839
840                  When opening an already open halt log, option  size  is  ig‐
841                  nored.
842
843                {notify, boolean()}:
844                  If true, the log owners are notified when certain log events
845                  occur. Defaults to false. The owners are  sent  one  of  the
846                  following messages when an event occurs:
847
848                  {disk_log, Node, Log, {wrap, NoLostItems}}:
849                    Sent  when a wrap log has filled up one of its files and a
850                    new file is opened. NoLostItems is the  number  of  previ‐
851                    ously logged items that were lost when truncating existing
852                    files.
853
854                  {disk_log, Node, Log, {truncated, NoLostItems}}:
855                    Sent when a log is truncated or reopened.  For  halt  logs
856                    NoLostItems  is  the  number  of  items written on the log
857                    since the disk log process  was  created.  For  wrap  logs
858                    NoLostItems is the number of items on all wrap log files.
859
860                  {disk_log, Node, Log, {read_only, Items}}:
861                    Sent  when  an  asynchronous  log attempt is made to a log
862                    file opened in read-only mode. Items is the items from the
863                    log attempt.
864
865                  {disk_log, Node, Log, {blocked_log, Items}}:
866                    Sent when an asynchronous log attempt is made to a blocked
867                    log that does not queue log attempts. Items is  the  items
868                    from the log attempt.
869
870                  {disk_log, Node, Log, {format_external, Items}}:
871                    Sent  when function alog/2 or alog_terms/2 is used for in‐
872                    ternally formatted logs. Items is the items from  the  log
873                    attempt.
874
875                  {disk_log, Node, Log, full}:
876                    Sent  when  an  attempt  to  log items to a wrap log would
877                    write more bytes than the limit set by option size.
878
879                  {disk_log, Node, Log, {error_status, Status}}:
880                    Sent when the error status changes. The  error  status  is
881                    defined by the outcome of the last attempt to log items to
882                    the log, or to truncate the log, or the last use of  func‐
883                    tion  sync/1, inc_wrap_file/1, or change_size/2. Status is
884                    either ok or {error, Error}, the  former  is  the  initial
885                    value.
886
887                {head, Head}:
888                  Specifies  a  header to be written first on the log file. If
889                  the log is a wrap log, the item Head  is  written  first  in
890                  each  new file. Head is to be a term if the format is inter‐
891                  nal, otherwise an iodata(). Defaults to  none,  which  means
892                  that no header is written first on the file.
893
894                {head_func, {M,F,A}}:
895                  Specifies  a  function to be called each time a new log file
896                  is opened. The call M:F(A) is assumed to return {ok,  Head}.
897                  The item Head is written first in each file. Head is to be a
898                  term if the format is internal, otherwise an iodata().
899
900                {mode, Mode}:
901                  Specifies if the log is to be opened in read-only  or  read-
902                  write mode. Defaults to read_write.
903
904                {quiet, Boolean}:
905                  Specifies if messages will be sent to error_logger on recov‐
906                  erable errors with the log files. Defaults to false.
907
908              open/1 returns {ok, Log} if the log file is successfully opened.
909              If  the file is successfully repaired, the tuple {repaired, Log,
910              {recovered, Rec}, {badbytes, Bad}} is returned, where Rec is the
911              number  of  whole  Erlang terms found in the file and Bad is the
912              number of bytes in the file that are non-Erlang terms.
913
914              When a disk log is opened in read-write mode, any  existing  log
915              file  is  checked for. If there is none, a new empty log is cre‐
916              ated, otherwise the existing file is opened at the position  af‐
917              ter  the  last logged item, and the logging of items starts from
918              there. If the format is internal and the existing  file  is  not
919              recognized  as  an  internally  formatted  log,  a tuple {error,
920              {not_a_log_file, FileName}} is returned.
921
922              open/1 cannot be used for changing the values of options  of  an
923              open log. When there are prior owners or users of a log, all op‐
924              tion values except name, linkto, and  notify  are  only  checked
925              against  the values supplied before as option values to function
926              open/1,  change_header/2,  change_notify/3,  or   change_size/2.
927              Thus,  none  of  the  options  except name is mandatory. If some
928              specified value differs from the current value, a tuple  {error,
929              {arg_mismatch, OptionName, CurrentValue, Value}} is returned.
930
931          Note:
932              If  an  owner  attempts to open a log as owner once again, it is
933              acknowledged with the return value {ok, Log}, but the  state  of
934              the disk log is not affected.
935
936
937              A log file can be opened more than once by giving different val‐
938              ues to option name or by using the same file when opening a  log
939              on  different  nodes. It is up to the user of module disk_log to
940              ensure that not more than one disk log process has write  access
941              to any file, otherwise the file can be corrupted.
942
943              If  an  attempt to open a log file for the first time fails, the
944              disk log process terminates with the EXIT message  {{failed,Rea‐
945              son},[{disk_log,open,1}]}.  The function returns {error, Reason}
946              for all other errors.
947
948       pid2name(Pid) -> {ok, Log} | undefined
949
950              Types:
951
952                 Pid = pid()
953                 Log = log()
954
955              Returns the log name given the pid of a disk log process on  the
956              current  node,  or  undefined if the specified pid is not a disk
957              log process.
958
959              This function is meant to be used for debugging only.
960
961       reopen(Log, File) -> ok | {error, reopen_error_rsn()}
962
963       reopen(Log, File, Head) -> ok | {error, reopen_error_rsn()}
964
965       breopen(Log, File, BHead) -> ok | {error, reopen_error_rsn()}
966
967              Types:
968
969                 Log = log()
970                 File = file:filename()
971                 Head = term()
972                 BHead = iodata()
973                 reopen_error_rsn() =
974                     no_such_log | nonode |
975                     {read_only_mode, log()} |
976                     {blocked_log, log()} |
977                     {same_file_name, log()} |
978                     {invalid_index_file, file:filename()} |
979                     {invalid_header, invalid_header()} |
980                     {file_error, file:filename(), file_error()}
981
982              Renames the log file to File and then recreates a new log  file.
983              If  a  wrap log exists, File is used as the base name of the re‐
984              named files. By default the header given to  open/1  is  written
985              first  in  the  newly  opened  log file, but if argument Head or
986              BHead is specified, this item is used instead. The header  argu‐
987              ment is used only once. Next time a wrap log file is opened, the
988              header given to open/1 is used.
989
990              reopen/2,3 are used for internally formatted logs, and breopen/3
991              for externally formatted logs.
992
993              Owners subscribing to notifications receive a truncate message.
994
995              Upon  failure to reopen the log, the disk log process terminates
996              with the EXIT  message  {{failed,Error},[{disk_log,Fun,Arity}]}.
997              Other  processes  having  requests  queued  receive  the message
998              {disk_log, Node, {error, disk_log_stopped}}.
999
1000       sync(Log) -> ok | {error, sync_error_rsn()}
1001
1002              Types:
1003
1004                 Log = log()
1005                 sync_error_rsn() =
1006                     no_such_log | nonode |
1007                     {read_only_mode, log()} |
1008                     {blocked_log, log()} |
1009                     {file_error, file:filename(), file_error()}
1010
1011              Ensures that the contents of the log are written  to  the  disk.
1012              This is usually a rather expensive operation.
1013
1014       truncate(Log) -> ok | {error, trunc_error_rsn()}
1015
1016       truncate(Log, Head) -> ok | {error, trunc_error_rsn()}
1017
1018       btruncate(Log, BHead) -> ok | {error, trunc_error_rsn()}
1019
1020              Types:
1021
1022                 Log = log()
1023                 Head = term()
1024                 BHead = iodata()
1025                 trunc_error_rsn() =
1026                     no_such_log | nonode |
1027                     {read_only_mode, log()} |
1028                     {blocked_log, log()} |
1029                     {invalid_header, invalid_header()} |
1030                     {file_error, file:filename(), file_error()}
1031
1032              Removes  all items from a disk log. If argument Head or BHead is
1033              specified, this item is written first  in  the  newly  truncated
1034              log,  otherwise  the  header given to open/1 is used. The header
1035              argument is used only once. Next time a wrap log file is opened,
1036              the header given to open/1 is used.
1037
1038              truncate/1  is used for both internally and externally formatted
1039              logs.
1040
1041              truncate/2 is used for internally  formatted  logs,  and  btrun‐
1042              cate/2 for externally formatted logs.
1043
1044              Owners subscribing to notifications receive a truncate message.
1045
1046              If  the  attempt to truncate the log fails, the disk log process
1047              terminates    with    the     EXIT     message     {{failed,Rea‐
1048              son},[{disk_log,Fun,Arity}]}.  Other  processes  having requests
1049              queued   receive   the   message   {disk_log,   Node,    {error,
1050              disk_log_stopped}}.
1051
1052       unblock(Log) -> ok | {error, unblock_error_rsn()}
1053
1054              Types:
1055
1056                 Log = log()
1057                 unblock_error_rsn() =
1058                     no_such_log | nonode |
1059                     {not_blocked, log()} |
1060                     {not_blocked_by_pid, log()}
1061
1062              Unblocks  a  log.  A  log  can only be unblocked by the blocking
1063              process.
1064

SEE ALSO

1066       file(3), wrap_log_reader(3)
1067
1068
1069
1070Ericsson AB                      kernel 8.3.2                      disk_log(3)
Impressum