Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages

  
 
  

home | help
disk_log(3)		   Erlang Module Definition		   disk_log(3)

NAME
       disk_log	- A disk-based term logging facility.

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

       Two types of logs are supported:

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

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

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

       Two formats of the log files are	supported:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

DATA TYPES
       log() = term()

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

       dlog_format() = external	| internal

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

       dlog_mode() = read_only | read_write

       dlog_type() = halt | wrap

       continuation()

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

       invalid_header()	= term()

       file_error() = term()

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

	      Types:

		 LocalLog = DistributedLog = log()

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

       alog(Log, Term) -> notify_ret()

       balog(Log, Bytes) -> notify_ret()

	      Types:

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

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

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

       alog_terms(Log, TermList) -> notify_ret()

       balog_terms(Log,	ByteList) -> notify_ret()

	      Types:

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

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

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

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

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

	      Types:

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

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

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

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

	      Types:

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

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

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

	      Types:

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

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

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

	      Types:

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

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

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

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

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

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

       chunk(Log, Continuation)	-> chunk_ret()

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

       bchunk(Log, Continuation) -> bchunk_ret()

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

	      Types:

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

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

	      The first	time chunk() (or bchunk()) is called, an initial  con-
	      tinuation,  the  atom  start,  must  be  provided. If a disk log
	      process is running on the	current	node, terms are	read from that
	      log. Otherwise, an individual distributed	log on some other node
	      is chosen, if such a log exists.

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

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

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

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

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

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

	      Types:

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

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

	      Terms are	read from the disk log running on Node.

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

	      Types:

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

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

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

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

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

	      Types:

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

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

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

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

       format_error(Error) -> io_lib:chars()

	      Types:

		 Error = term()

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

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

	      Types:

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

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

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

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

	      Types:

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

	      Returns a	list of	{Tag, Value} pairs describing the  log.	 If  a
	      disk  log	 process  is  running on the current node, that	log is
	      used as source of	information, otherwise an individual  distrib-
	      uted log on some other node is chosen, if	such a log exists.

	      The following pairs are returned for all logs:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	      Types:

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

	      lclose/1	closes a local log or an individual distributed	log on
	      the current node.

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

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

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

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

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

	      Types:

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

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

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

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

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

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

	      Types:

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

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

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

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

       open(ArgL) -> open_ret()	| dist_open_ret()

	      Types:

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

	      Parameter	ArgL is	a list of the following	options:

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

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

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

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

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

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

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

		{size, Size}:
		  Log size.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	      open/1 returns {ok, Log} if the log file is successfully opened.
	      If the file is successfully repaired, the	tuple {repaired,  Log,
	      {recovered, Rec},	{badbytes, Bad}} is returned, where Rec	is the
	      number of	whole Erlang terms found in the	file and  Bad  is  the
	      number  of  bytes	 in the	file that are non-Erlang terms.	If the
	      parameter	distributed is specified, open/1  returns  a  list  of
	      successful  replies  and a list of erroneous replies. Each reply
	      is tagged	with the node name.

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

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

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

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

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

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

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

	      Types:

		 Pid = pid()
		 Log = log()

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

	      This function is meant to	be used	for debugging only.

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

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

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

	      Types:

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

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

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

	      Owners subscribing to notifications receive a truncate message.

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

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

	      Types:

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

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

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

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

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

	      Types:

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

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

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

	      Owners subscribing to notifications receive a truncate message.

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

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

	      Types:

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

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

SEE ALSO
       file(3),	pg2(3),	wrap_log_reader(3)

Ericsson AB			  kernel 6.3			   disk_log(3)

NAME | DESCRIPTION | DATA TYPES | EXPORTS | SEE ALSO

Want to link to this manual page? Use this URL:
<https://www.freebsd.org/cgi/man.cgi?query=disk_log&sektion=3&manpath=FreeBSD+12.2-RELEASE+and+Ports>

home | help