---
name: "log"
section: "3bobcat"
platform: "linux"
package: "libbobcat-dev"
version: "6.07.01-2"
release: "Debian 13 (Trixie)"
platforms: ["linux"]
url: "https://new.carta.tech/log/3bobcat"
---

# log(3bobcat)

std::ostream handling log messages

## NAME

FBB::Log - *std::ostream* handling log messages

## SYNOPSIS

**#include \<bobcat/log\>**\
 Linking option: *-lbobcat*\

## DESCRIPTION

The class **FBB::Log** defines an *std::ostream* using an *FBB::LogBuf* *std::streambuf*. It is used to send log-messages to the (r)syslog stream or to a (configurable) file. Refer to the [**logbuf**(3bobcat)](/logbuf/3bobcat.md) man-page for details about *LogBuf*.

Which (parts of) messages are actually logged can be configured using **FBB::level** in combination with the *Log* member *setLevel* or using the function operator in combination with the *str* member (see the the members *operator()* and *str*). By default all information that is inserted into a *Log* object is logged.

Objects of the *level* class (cf. [**level**(3bobcat)](/level/3bobcat.md)) can be inserted specifying insertion \`forces’ for the information that is subsequently inserted into *Log* objects. Only if these\`forces’ exceed the *Log* object’s insertion \`resistances’ (see the member *setLevel*) then the information is logged.

A single log-insertion statement may contain multiple *level* calls. If so, then each *level* call updates the \`force’ of insertions following the *level* call.

Information inserted into *Log* objects without inserting *level* objects (or before the first *level* object) is always logged (see also the **Examples** section).

Alternatively information may be logged using category-selector characters. The member *str(std::string const &active)* defines the characters that can be used to define a non-hierarchical logging process. E.g., *str("abc")* defines the log-identifying characters *’a’,* *’b’,* and *’c’* which can then be used to define log-statements for each of those categories. These log-identifying characters may be redefined, activating only those log-statements whose identifying characters were specified in the last call of the *str* member.

Although hierarchical and non-hierarchical logging can both be used in a single program, they operate in a mutually exclusive way: once hierarchical logging is defined the non-hierarchical categories are erased, and once non-hierarchical categories are defined the hierarchical resistance level is set to its maximum value, effectively suppressing hierarchical logging.

By default logged messages are prepended by time stamps. Following the time stamps a delimiter (by default a single space character) is inserted. Delimiters are immediately appended to time stamps and inserted messages are immediately appended to delimiters. When specifying text as delimiters consider starting and ending the delimiter’s text with space characters to visually separate the delimiter from the time stamp and from the subsequently inserted information.

## NAMESPACE

**FBB**\
 All constructors, members, operators and manipulators, mentioned in this man-page, are defined in the namespace **FBB**.

## INHERITS FROM

*std::ostream*

## ENUMERATIONS

The enumeration *TimeStamps* is defined in the namespace *FBB*, primarily for initializing *FBB::LogBuf* objects. It is used with *Log* members as well. It has the following values:

- o

  **NOTIMESTAMPS**:\
   Log-messages will not have timestamps prepended to them.

- o

  **TIMESTAMPS**:\
   Log-messages will have timestamps prepended to them.

- o

  **UTCTIMESTAMPS**:\
   Log-messages will have timestamps showing the UTC time prepended to them.

The enumeration *LogManipulator* is used to handle special or exceptional situations through manipulators. It is defined in the namespace *FBB* and has the following two values:

- o

  **FATAL**:\
   When inserting *FATAL* into a *Log* object an *FBB::Exception* exception is thrown (see *operator\<\<* below);

-

  - o

  **nl**:\
   When inserting *nl* into a *Log* object a *\\n* character is inserted into the current line. If time stamps are requested the the next line will not begin with a time stamp. It is used to allow a single log message to occupy multiple textual lines. The next logged line is not indented over the width of the omitted time stamp. If that’s preferred: the time stamp occupies 15 character positions (not counting the width of the delimiter, see the **CONSTRUCTORS** section below). If a *level* specification is active, it remains active at insertions following *nl*.

-

  - o

  **fnl**:\
   When inserting *fnl* (forced new line) into a *Log* object the current line ends even if the currently active insertion \`force’ (set by *level*) is lower than the *Log* object’s \`resistance’ level. If a *level* specification is active, it remains active at insertions following *fnl*.

-

  - o

  **endl** or **\\n**:\
   When inserting *endl* or *\\n* the current line is ended and the next logged line starts with a timestamp (unless timestamps are suppressed). The *endl* manipulator is the standard *ostream* manipulator: when inserted into a *Log* object its buffer is flushed. The scope of a *level* specification ends at *\\n* or *endl*. E.g.,

  ```
  log.setLevel(2);
  log << level(1) << "first line\n"
         "second line\n";
  ```

  results in *second line* (preceded by a timestamp) being logged.

## CONSTRUCTORS

- o

  **Log()**:\
   The default constructor creates a *Log* object which isn’t yet associated with a stream to log messages on. The member *open* (see below) may be used to define such a stream.  By default, all messages are preceded by a time stamp (see the description of the member *setTimestamp* below), and a single space character is inserted as delimiter immediately beyond the time stamp. The member *open* can be used to modify the default delimiter.

-

  - o

  **Log(std::ostream &out, char const \*delim = " ")**:\
   This constructor creates a *Log* object logging its messages to the provided *std::ostream* object. By default, all messages are preceded by a time stamp (see the description of the member *setTimestamp* below).  The parameter *delim* is inserted immediately beyond the time stamp. If a delimiter should not be used an empty string or a 0-pointer may be specified.

-

  - o

  **FBB::Log(std::string const &filename,** **std::ios::openmode mode = std::ios::out \| std::ios::app,** **char const \*delim = " ")**:\
   This constructor creates a *Log* object logging its messages to the named file. If *filename == "&1"* logmessages are written to the standard output stream. If *filename == "&2"* logmessages are written to the standard error stream.  By default the file is created if not existing, and all messages are appended to the stream. Also by default all messages are preceded by time stamps (see the description of the member *setTimestamp* below). The parameter *delim* is inserted immediately beyond the time stamp.  If a delimiter should not be used an empty string or a 0-pointer may be specified.

Copy and move constructors (and assignment operators) are not available.

## MEMBER FUNCTIONS

All members of *std::ostream* are available, as *Log* inherits from this class.

- o

  **size\_t level() const**:\
   This member returns the currently set log level (i.e., the value set at the latest *setLevel()* call). By default, the level is set to zero, meaning that all information is inserted into the log stream;

-

  - o

  **std::ostream &level(size\_t useLevel)**:\
   This member defines the log-level of messages that are going to be inserted. Messages are inserted when *useLevel* is at least equal to the level specified by *setLevel*. The maximum level is *std::numeric\_limits\<size\_t\>::max()*. If not even such messages should be inserted into the *ostream*, then the stream should be deactivated, using *off()* (see below). The level that is specified by this member remains active until another *level* call changes it. Alternatively, the level of inserted messages may be specified by inserting a *FBB::level* manipulator into a *Log* object (see [**level**(3bobcat)](/level/3bobcat.md));

-

  - o

  **void off()**:\
   Prevents log messages from being generated. It is cancelled by calling *on* (see below);

-

  - o

  **void on(size\_t logLevel = 0)**:\
   Reactivates logging (e.g., after *off* was previously called) setting the level that inserted information must at least have (to *logLevel*). Following *on* and unless specified otherwise (e.g., by using *level*) all inserted information is accpted by the *Log* object;

-

  - o

  **void open(std::string const &filename,** **std::ios::openmode mode = std::ios::out \| std::ios::app,** **char const \*delim = " ")**:\
   This member (re)associates a *Log* object with the named file. If *filename == "&1"* the logmessages will be written to the standard output stream. If *filename == "&2"* the logmessages will be written to the standard error stream.  By default the file is created if not existing, and all messages are appended to the stream. Also by default all messages are preceded by time stamps (see the description of the member *setTimestamp* below).  The parameter *delim* is inserted immediately beyond the time stamp.  If a delimiter should not be used an empty string or a 0-pointer may be specified;

-

  - o

  **void setLevel(size\_t resistance)**:\
   Defines the \`resistance’ when inserting information into a *Log* object. Information is inserted if the level set by the *level* member is at least equal to *resistance*.  Following *setLevel* and unless specified otherwise (e.g., by using *level*) all inserted information is accpted by the *Log* object. *setLevel* does not reactivate logging after calling *off*. To reactivate logging after calling *off on* must be called;

-

  - o

  **void setTimestamp(FBB::TimeStamps stamp, char const \*delim = " ")**:\
   The member function (de)activates time stamp prepending. Use the value *FBB::TIMESTAMPS* to prepend time stamps, *FBB::NOTIMESTAMPS* suppresses time stamps.  A timestamp consists of 15 characters showing the abbreviated month’s name, two-digits specifying the day number of the month, and the (local or UTC) time of the current message, as usually appearing in messages in */var/log* files. E.g., *Aug 05 13:52:23*. The parameter *delim* is inserted immediately beyond the time stamp. If a delimiter is inappropriate, an empty string or a 0-pointer may be specified. When specifying *stamps* as *FBB::NOTIMESTAMPS delim* also is ignored.

-

  - o

  **std::string const &str() const**:\
   The currently set of characters that can be specified by *Log’s* function call operator to insert a log-entry is returned. By default no characters are specified;

-

  - o

  **void str(std::string const &chars)**:\
   The argument to this member is a *std::string* defining the characters that can be specified by *Log’s* function call operator to insert a log-entry. If the function call operator specifies a character which is not specified in *chars* then that log message is ignored.  By default no characters are specified.

## STATIC MEMBERS

- o

  **FBB::Log &initialize(std::string const &filename,** **std::ios::openmode mode = std::ios::out \| std::ios::app,** **char const \*delim = " ")**:\
   Returns a reference to a static *Log* object. It may only be called once, or an *FBB::Exception* exception is thrown. It associates a static *Log* object with the named file.

-

  If *filename == "&1"* logmessages are written to the standard output stream. If *filename == "&2"* logmessages are written to the standard error stream.  By default the file is created if not existing, and all messages are appended to the stream. Also by default all messages are preceded by time stamps (see the description of the member *setTimestamp* below).  The parameter *delim* is inserted immediately beyond the time stamp.  If a delimiter should not be used an empty string or a 0-pointer may be specified;

-

  - o

  **FBB::Log &instance()**:\
   Returns a reference to a static *Log* object, available after calling *Log::initialize*. If called before *Log::initialize()* an *FBB::Exception* exception is thrown.

## OVERLOADED OPERATORS

- o

  **Log &operator()(char ch)**:\
   If the function’s argument is found in the characters specified at the *str* member subsequent insertions until (including) inserting *std::endl* or the *fnl* or *FATAL LogManipulator* are logged. If the function’s argument is not found in the characters specified at the *str* member then subsequent insertions are ignored. By calling this member hierarchical insertions are suppressed until the *setLevel* member is called;

-

  - o

  **Log &operator\<\<(Log &, LogManipulator)**:\
   This operator inserts a *LogManipulator* into a *Log* object. When inserting *FBB::FATAL* an *FBB::Exception* is thrown; when inserting *FBB::nl* the line is terminated, and the next insertion won’t start with a time stamp; when inserting *FBB::fnl* the line is terminated, and the next insertion will start with a time stamp (if applicable). After calling this insertion operator with the *FATAL* or *fnl LogManipulator* value category-based insertions are suppressed until the function-call operator is called;

-

  - o

  **Log &operator\<\<(Log &log, Type const &type)**:\
   This operator is defined as a template, where *Type* represents any type that can be inserted into a *std::ostream*. The value *type* is inserted into the *Log* object;

-

  - o

  **Log &operator\<\<(Log &log, Type &(\*fun)(Type &type))**:\
   In this operator *fun* represents the standard *ostream* and *ios\_base* manipulators, allowing the insertion of manipulators like *std::endl* and *std::setw* into *Log* objects;

-

  - o

  **std::ostream &::operator\<\<(std::ostream &str, FBB::LogManipulator)**:\
   This operator is defined outside of the *FBB* namespace. It is kept for backward compatibility with previous **bobcat** versions, and  calls *operator\<\<(Log, LogManipulatr)* when *&str* can dynamically be casted to a *Log \**.  If not, then the operator performs no actions.

## EXAMPLE

```
#include <iostream>
#include <iomanip>
#include <bobcat/log>
#include <bobcat/level>
using namespace std;
using namespace FBB;
int main()
{
//    Log &log = Log::initialize("&1"); // uses the static Log object
    Log log;                        // explicitly defining a Log object
//    log.open("/tmp/out");           // or at once: Log log{ "/tmp/out" }
    log << "This message is written to cout" << nl <<
           setw(16) << ’ ’ << "occupying multiple lines\n";
    log.off();
    log << "This message is not shown\n";
    log << "This message is not shown\n";
    log << fnl;
    log << "This message is not shown\n";
    log.on(2);
    log << "This message is shown\n";
    log << level(0) << "not shown" << level(2) << "shown at level 2\n";
    log << level(3) << "at level(3)" << level(1) << "not shown" << fnl;
    log << "separate new line\n";
    log << level(2) << "in business again\n";
    log << "final line\n";
    log.str("ab");
    log(’a’) << "hello a!" << endl;
    log(’b’) << "hello b!" << nl <<
                setw(16) << ’ ’ << "so far, so good" << endl;
    log << "not shown" << endl;
    log(’c’) << "not shown\n";
    log << "not shown\n";
    log.setLevel(2);
    log << level(2) << "in business again\n";
}
```

## FILES

*bobcat/log* - defines the class interface

## SEE ALSO

[**bobcat**(7)](/bobcat/7.md), [**exception**(3bobcat)](/exception/3bobcat.md), [**level**(3bobcat)](/level/3bobcat.md), [**logbuf**(3bobcat)](/logbuf/3bobcat.md), [**syslogstream**(3bobcat)](/syslogstream/3bobcat.md)

## BUGS

The *nl* and *fnl* manipulators are received by the *Log* objects’ *LogBufs* as, respectively, characters 0 and 1. Since log files in practice only received printable characters this should not cause any problems.

## BOBCAT PROJECT FILES

- o

  *https://fbb-git.gitlab.io/bobcat/*: gitlab project page;

Debian Bobcat project files:

- o

  *libbobcat6*: debian package containing the shared library, changelog and copyright note;

- o

  *libbobcat-dev*: debian package containing the static library, headers, manual pages, and developer info;

## BOBCAT

Bobcat is an acronym of \`Brokken’s Own Base Classes And Templates’.

## COPYRIGHT

This is free software, distributed under the terms of the GNU General Public License (GPL).

## AUTHOR

Frank B. Brokken (**f.b.brokken@rug.nl**).
