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