\doxysection{src/core/logging.c File Reference}
\label{logging_8c}\index{src/core/logging.c@{src/core/logging.c}}


Debugging/\+Logging support code.  


{\ttfamily \#include \char`\"{}config.\+h\char`\"{}}\newline
{\ttfamily \#include $<$stdarg.\+h$>$}\newline
{\ttfamily \#include $<$stdlib.\+h$>$}\newline
{\ttfamily \#include $<$stdio.\+h$>$}\newline
{\ttfamily \#include $<$string.\+h$>$}\newline
{\ttfamily \#include $<$unistd.\+h$>$}\newline
{\ttfamily \#include $<$time.\+h$>$}\newline
{\ttfamily \#include $<$sys/time.\+h$>$}\newline
{\ttfamily \#include $<$sys/types.\+h$>$}\newline
{\ttfamily \#include $<$sys/stat.\+h$>$}\newline
{\ttfamily \#include $<$fcntl.\+h$>$}\newline
{\ttfamily \#include $<$errno.\+h$>$}\newline
{\ttfamily \#include $<$pthread.\+h$>$}\newline
{\ttfamily \#include $<$osmocom/core/talloc.\+h$>$}\newline
{\ttfamily \#include $<$osmocom/core/utils.\+h$>$}\newline
{\ttfamily \#include $<$osmocom/core/logging.\+h$>$}\newline
{\ttfamily \#include $<$osmocom/core/timer.\+h$>$}\newline
{\ttfamily \#include $<$osmocom/core/thread.\+h$>$}\newline
{\ttfamily \#include $<$osmocom/core/select.\+h$>$}\newline
{\ttfamily \#include $<$osmocom/core/write\+\_\+queue.\+h$>$}\newline
{\ttfamily \#include $<$osmocom/core/gsmtap\+\_\+util.\+h$>$}\newline
{\ttfamily \#include $<$osmocom/vty/logging.\+h$>$}\newline
\doxysubsection*{Macros}
\begin{DoxyCompactItemize}
\item 
\#define \textbf{ TRACE}(probe)
\item 
\#define \textbf{ TRACE\+\_\+\+ENABLED}(probe)~(0)
\item 
\#define \textbf{ MAX\+\_\+\+LOG\+\_\+\+SIZE}~4096
\item 
\#define \textbf{ LOG\+\_\+\+WQUEUE\+\_\+\+LEN}~156
\item 
\#define \textbf{ INT2\+IDX}(\textbf{ x})~(-\/1$\ast$(\textbf{ x})-\/1)
\end{DoxyCompactItemize}
\doxysubsection*{Functions}
\begin{DoxyCompactItemize}
\item 
\textbf{ osmo\+\_\+static\+\_\+assert} (\textbf{ \+\_\+\+LOG\+\_\+\+CTX\+\_\+\+COUNT}$<$=\textbf{ ARRAY\+\_\+\+SIZE}(((struct \textbf{ log\+\_\+context} $\ast$) NULL) -\/$>$ctx), enum\+\_\+logging\+\_\+ctx\+\_\+items\+\_\+fit\+\_\+in\+\_\+struct\+\_\+log\+\_\+context)
\item 
\textbf{ osmo\+\_\+static\+\_\+assert} (\textbf{ \+\_\+\+LOG\+\_\+\+FLT\+\_\+\+COUNT}$<$=\textbf{ ARRAY\+\_\+\+SIZE}(((struct \textbf{ log\+\_\+target} $\ast$) NULL) -\/$>$filter\+\_\+data), enum\+\_\+logging\+\_\+filters\+\_\+fit\+\_\+in\+\_\+log\+\_\+target\+\_\+filter\+\_\+data)
\item 
\textbf{ osmo\+\_\+static\+\_\+assert} (\textbf{ \+\_\+\+LOG\+\_\+\+FLT\+\_\+\+COUNT}$<$=8 $\ast$sizeof(((struct \textbf{ log\+\_\+target} $\ast$) NULL) -\/$>$filter\+\_\+map), enum\+\_\+logging\+\_\+filters\+\_\+fit\+\_\+in\+\_\+log\+\_\+target\+\_\+filter\+\_\+map)
\item 
\textbf{ LLIST\+\_\+\+HEAD} (\textbf{ osmo\+\_\+log\+\_\+target\+\_\+list})
\item 
static void \textbf{ log\+\_\+cache\+\_\+update\+\_\+all} (void)
\begin{DoxyCompactList}\small\item\em Updates cache for all targets for all categies, caller must hold osmo\+\_\+log\+\_\+tgt\+\_\+mutex. \end{DoxyCompactList}\item 
void \textbf{ log\+\_\+cache\+\_\+update} (int mapped\+\_\+subsys, uint8\+\_\+t enabled, uint8\+\_\+t \textbf{ level})
\begin{DoxyCompactList}\small\item\em Updates single cache entry, caller must hold osmo\+\_\+log\+\_\+tgt\+\_\+mutex. \end{DoxyCompactList}\item 
static bool \textbf{ log\+\_\+cache\+\_\+check} (int mapped\+\_\+subsys, int \textbf{ level})
\begin{DoxyCompactList}\small\item\em Queries log level cache. \end{DoxyCompactList}\item 
void \textbf{ log\+\_\+enable\+\_\+multithread} (void)
\begin{DoxyCompactList}\small\item\em Enable multithread support (mutex) in libosmocore logging system. \end{DoxyCompactList}\item 
void \textbf{ log\+\_\+tgt\+\_\+mutex\+\_\+lock\+\_\+impl} (void)
\begin{DoxyCompactList}\small\item\em Acquire the osmo\+\_\+log\+\_\+tgt\+\_\+mutex. \end{DoxyCompactList}\item 
void \textbf{ log\+\_\+tgt\+\_\+mutex\+\_\+unlock\+\_\+impl} (void)
\begin{DoxyCompactList}\small\item\em Release the osmo\+\_\+log\+\_\+tgt\+\_\+mutex. \end{DoxyCompactList}\item 
void \textbf{ assert\+\_\+loginfo} (const char $\ast$src)
\item 
static int \textbf{ subsys\+\_\+lib2index} (int \textbf{ subsys})
\item 
int \textbf{ log\+\_\+parse\+\_\+level} (const char $\ast$lvl)
\begin{DoxyCompactList}\small\item\em Parse a human-\/readable log level into a numeric value. \end{DoxyCompactList}\item 
const char $\ast$ \textbf{ log\+\_\+level\+\_\+str} (unsigned int lvl)
\begin{DoxyCompactList}\small\item\em convert a numeric log level into human-\/readable string \end{DoxyCompactList}\item 
int \textbf{ log\+\_\+parse\+\_\+category} (const char $\ast$category)
\begin{DoxyCompactList}\small\item\em parse a human-\/readable log category into numeric form \end{DoxyCompactList}\item 
void \textbf{ log\+\_\+parse\+\_\+category\+\_\+mask} (struct \textbf{ log\+\_\+target} $\ast$target, const char $\ast$\+\_\+mask)
\begin{DoxyCompactList}\small\item\em parse the log category mask \end{DoxyCompactList}\item 
static const char $\ast$ \textbf{ color} (int \textbf{ subsys})
\item 
static const char $\ast$ \textbf{ level\+\_\+color} (int \textbf{ level})
\item 
const char $\ast$ \textbf{ log\+\_\+category\+\_\+name} (int \textbf{ subsys})
\item 
static const char $\ast$ \textbf{ const\+\_\+basename} (const char $\ast$path)
\item 
static int \textbf{ \+\_\+output\+\_\+buf} (char $\ast$buf, int buf\+\_\+len, struct \textbf{ log\+\_\+target} $\ast$target, unsigned int \textbf{ subsys}, unsigned int \textbf{ level}, const char $\ast$\textbf{ file}, int line, int cont, const char $\ast$format, va\+\_\+list ap)
\begin{DoxyCompactList}\small\item\em main output formatting function for log lines. \end{DoxyCompactList}\item 
static void \textbf{ \+\_\+output} (struct \textbf{ log\+\_\+target} $\ast$target, unsigned int \textbf{ subsys}, unsigned int \textbf{ level}, const char $\ast$\textbf{ file}, int line, int cont, const char $\ast$format, va\+\_\+list ap)
\item 
static int \textbf{ map\+\_\+subsys} (int \textbf{ subsys})
\item 
static bool \textbf{ should\+\_\+log\+\_\+to\+\_\+target} (struct \textbf{ log\+\_\+target} $\ast$tar, int \textbf{ subsys}, int \textbf{ level})
\item 
void \textbf{ osmo\+\_\+vlogp} (int \textbf{ subsys}, int \textbf{ level}, const char $\ast$\textbf{ file}, int line, int cont, const char $\ast$format, va\+\_\+list ap)
\begin{DoxyCompactList}\small\item\em vararg version of logging function \end{DoxyCompactList}\item 
void \textbf{ logp} (int \textbf{ subsys}, const char $\ast$\textbf{ file}, int line, int cont, const char $\ast$format,...)
\begin{DoxyCompactList}\small\item\em logging function used by \doxyref{DEBUGP()}{p.}{group__logging_gab805322bc0052e2cb6b6a6557fd59e91} macro \end{DoxyCompactList}\item 
void \textbf{ logp2} (int \textbf{ subsys}, unsigned int \textbf{ level}, const char $\ast$\textbf{ file}, int line, int cont, const char $\ast$format,...)
\begin{DoxyCompactList}\small\item\em logging function used by \doxyref{LOGP()}{p.}{group__logging_ga7e3a9f703edc9b95a8548a656a6f686d} macro \end{DoxyCompactList}\item 
void void \textbf{ logp\+\_\+stub} (const char $\ast$\textbf{ file}, int line, int cont, const char $\ast$format,...)
\item 
void \textbf{ log\+\_\+add\+\_\+target} (struct \textbf{ log\+\_\+target} $\ast$target)
\begin{DoxyCompactList}\small\item\em Register a new log target with the logging core. \end{DoxyCompactList}\item 
void \textbf{ log\+\_\+del\+\_\+target} (struct \textbf{ log\+\_\+target} $\ast$target)
\begin{DoxyCompactList}\small\item\em Unregister a log target from the logging core. \end{DoxyCompactList}\item 
void \textbf{ log\+\_\+reset\+\_\+context} (void)
\begin{DoxyCompactList}\small\item\em Reset (clear) the logging context. \end{DoxyCompactList}\item 
int \textbf{ log\+\_\+set\+\_\+context} (uint8\+\_\+t ctx\+\_\+nr, void $\ast$value)
\begin{DoxyCompactList}\small\item\em Set the logging context. \end{DoxyCompactList}\item 
void \textbf{ log\+\_\+set\+\_\+all\+\_\+filter} (struct \textbf{ log\+\_\+target} $\ast$target, int all)
\begin{DoxyCompactList}\small\item\em Enable the \doxyref{LOG\+\_\+\+FLT\+\_\+\+ALL}{p.}{group__logging_gga06c744d8d9104f275d8b8568c09fd144ab84e1400c3d6394a42c59ebb5804d35f} log filter. \end{DoxyCompactList}\item 
void \textbf{ log\+\_\+set\+\_\+use\+\_\+color} (struct \textbf{ log\+\_\+target} $\ast$target, int use\+\_\+color)
\begin{DoxyCompactList}\small\item\em Enable or disable the use of colored output. \end{DoxyCompactList}\item 
void \textbf{ log\+\_\+set\+\_\+print\+\_\+timestamp} (struct \textbf{ log\+\_\+target} $\ast$target, int print\+\_\+timestamp)
\begin{DoxyCompactList}\small\item\em Enable or disable printing of timestamps while logging. \end{DoxyCompactList}\item 
void \textbf{ log\+\_\+set\+\_\+print\+\_\+extended\+\_\+timestamp} (struct \textbf{ log\+\_\+target} $\ast$target, int print\+\_\+timestamp)
\begin{DoxyCompactList}\small\item\em Enable or disable printing of extended timestamps while logging. \end{DoxyCompactList}\item 
void \textbf{ log\+\_\+set\+\_\+print\+\_\+tid} (struct \textbf{ log\+\_\+target} $\ast$target, int print\+\_\+tid)
\begin{DoxyCompactList}\small\item\em Enable or disable printing of timestamps while logging. \end{DoxyCompactList}\item 
void \textbf{ log\+\_\+set\+\_\+print\+\_\+filename} (struct \textbf{ log\+\_\+target} $\ast$target, int print\+\_\+filename)
\begin{DoxyCompactList}\small\item\em Use \doxyref{log\+\_\+set\+\_\+print\+\_\+filename2()}{p.}{group__logging_ga878f19493806866c6dbf2d7741aaa9e6} instead. \end{DoxyCompactList}\item 
void \textbf{ log\+\_\+set\+\_\+print\+\_\+filename2} (struct \textbf{ log\+\_\+target} $\ast$target, enum \textbf{ log\+\_\+filename\+\_\+type} lft)
\begin{DoxyCompactList}\small\item\em Enable or disable printing of the filename while logging. \end{DoxyCompactList}\item 
void \textbf{ log\+\_\+set\+\_\+print\+\_\+filename\+\_\+pos} (struct \textbf{ log\+\_\+target} $\ast$target, enum \textbf{ log\+\_\+filename\+\_\+pos} pos)
\begin{DoxyCompactList}\small\item\em Set the position where on a log line the source file info should be logged. \end{DoxyCompactList}\item 
void \textbf{ log\+\_\+set\+\_\+print\+\_\+category} (struct \textbf{ log\+\_\+target} $\ast$target, int print\+\_\+category)
\begin{DoxyCompactList}\small\item\em Enable or disable printing of the category name. \end{DoxyCompactList}\item 
void \textbf{ log\+\_\+set\+\_\+print\+\_\+category\+\_\+hex} (struct \textbf{ log\+\_\+target} $\ast$target, int print\+\_\+category\+\_\+hex)
\begin{DoxyCompactList}\small\item\em Enable or disable printing of the category number in hex (\textquotesingle{}$<$000b$>$\textquotesingle{}). \end{DoxyCompactList}\item 
void \textbf{ log\+\_\+set\+\_\+print\+\_\+level} (struct \textbf{ log\+\_\+target} $\ast$target, int print\+\_\+level)
\begin{DoxyCompactList}\small\item\em Enable or disable printing of the log level name. \end{DoxyCompactList}\item 
void \textbf{ log\+\_\+set\+\_\+log\+\_\+level} (struct \textbf{ log\+\_\+target} $\ast$target, int log\+\_\+level)
\begin{DoxyCompactList}\small\item\em Set the global log level for a given log target. \end{DoxyCompactList}\item 
void \textbf{ log\+\_\+set\+\_\+category\+\_\+filter} (struct \textbf{ log\+\_\+target} $\ast$target, int category, int enable, int \textbf{ level})
\begin{DoxyCompactList}\small\item\em Set a category filter on a given log target. \end{DoxyCompactList}\item 
static int \textbf{ \+\_\+file\+\_\+wq\+\_\+write\+\_\+cb} (struct \textbf{ osmo\+\_\+fd} $\ast$ofd, struct \textbf{ msgb} $\ast$\textbf{ msg})
\item 
static void \textbf{ \+\_\+file\+\_\+output\+\_\+stream} (struct \textbf{ log\+\_\+target} $\ast$target, unsigned int \textbf{ level}, const char $\ast$log)
\item 
static void \textbf{ \+\_\+file\+\_\+raw\+\_\+output} (struct \textbf{ log\+\_\+target} $\ast$target, int \textbf{ subsys}, unsigned int \textbf{ level}, const char $\ast$\textbf{ file}, int line, int cont, const char $\ast$format, va\+\_\+list ap)
\item 
struct \textbf{ log\+\_\+target} $\ast$ \textbf{ log\+\_\+target\+\_\+create} (void)
\begin{DoxyCompactList}\small\item\em Create a new log target skeleton. \end{DoxyCompactList}\item 
struct \textbf{ log\+\_\+target} $\ast$ \textbf{ log\+\_\+target\+\_\+create\+\_\+stderr} (void)
\begin{DoxyCompactList}\small\item\em Create the STDERR log target. \end{DoxyCompactList}\item 
struct \textbf{ log\+\_\+target} $\ast$ \textbf{ log\+\_\+target\+\_\+create\+\_\+file\+\_\+stream} (const char $\ast$fname)
\begin{DoxyCompactList}\small\item\em Create a new file-\/based log target using buffered, blocking stream output. \end{DoxyCompactList}\item 
int \textbf{ log\+\_\+target\+\_\+file\+\_\+switch\+\_\+to\+\_\+stream} (struct \textbf{ log\+\_\+target} $\ast$target)
\begin{DoxyCompactList}\small\item\em switch from non-\/blocking/write-\/queue to blocking + buffered stream output \end{DoxyCompactList}\item 
int \textbf{ log\+\_\+target\+\_\+file\+\_\+switch\+\_\+to\+\_\+wqueue} (struct \textbf{ log\+\_\+target} $\ast$target)
\begin{DoxyCompactList}\small\item\em switch from blocking + buffered file output to non-\/blocking write-\/queue based output. \end{DoxyCompactList}\item 
struct \textbf{ log\+\_\+target} $\ast$ \textbf{ log\+\_\+target\+\_\+create\+\_\+file} (const char $\ast$fname)
\begin{DoxyCompactList}\small\item\em Create a new file-\/based log target using non-\/blocking write\+\_\+queue. \end{DoxyCompactList}\item 
struct \textbf{ log\+\_\+target} $\ast$ \textbf{ log\+\_\+target\+\_\+find} (enum \textbf{ log\+\_\+target\+\_\+type} \textbf{ type}, const char $\ast$fname)
\begin{DoxyCompactList}\small\item\em Find a registered log target. \end{DoxyCompactList}\item 
void \textbf{ log\+\_\+target\+\_\+destroy} (struct \textbf{ log\+\_\+target} $\ast$target)
\begin{DoxyCompactList}\small\item\em Unregister, close and delete a log target. \end{DoxyCompactList}\item 
int \textbf{ log\+\_\+target\+\_\+file\+\_\+reopen} (struct \textbf{ log\+\_\+target} $\ast$target)
\begin{DoxyCompactList}\small\item\em close and re-\/open a log file (for log file rotation) \end{DoxyCompactList}\item 
int \textbf{ log\+\_\+targets\+\_\+reopen} (void)
\begin{DoxyCompactList}\small\item\em close and re-\/open all log files (for log file rotation) \end{DoxyCompactList}\item 
int \textbf{ log\+\_\+cache\+\_\+enable} (void)
\begin{DoxyCompactList}\small\item\em Enable the log level lookup cache to bypass string formatting and other code for log statements which are not actually enabled/needed by any existing log target. \end{DoxyCompactList}\item 
int \textbf{ log\+\_\+init} (const struct \textbf{ log\+\_\+info} $\ast$inf, void $\ast$ctx)
\begin{DoxyCompactList}\small\item\em Initialize the Osmocom logging core. \end{DoxyCompactList}\item 
void \textbf{ log\+\_\+fini} (void)
\item 
int \textbf{ log\+\_\+check\+\_\+level} (int \textbf{ subsys}, unsigned int \textbf{ level})
\begin{DoxyCompactList}\small\item\em Check whether a log entry will be generated. \end{DoxyCompactList}\end{DoxyCompactItemize}
\doxysubsection*{Variables}
\begin{DoxyCompactItemize}
\item 
struct \textbf{ log\+\_\+info} $\ast$ \textbf{ osmo\+\_\+log\+\_\+info}
\item 
static struct \textbf{ log\+\_\+context} \textbf{ log\+\_\+context}
\item 
void $\ast$ \textbf{ tall\+\_\+log\+\_\+ctx} = NULL
\item 
static \+\_\+\+\_\+thread long int \textbf{ logging\+\_\+tid}
\item 
static volatile uint8\+\_\+t $\ast$ \textbf{ log\+\_\+level\+\_\+lookup\+\_\+cache}
\begin{DoxyCompactList}\small\item\em One global copy that contains the union of log levels for all targets for all categories, used for quick lock free checks of log targets. \end{DoxyCompactList}\item 
static pthread\+\_\+mutex\+\_\+t \textbf{ osmo\+\_\+log\+\_\+tgt\+\_\+mutex}
\begin{DoxyCompactList}\small\item\em This mutex must be held while using osmo\+\_\+log\+\_\+target\+\_\+list or any of its log\+\_\+targets in a multithread program. \end{DoxyCompactList}\item 
static bool \textbf{ osmo\+\_\+log\+\_\+tgt\+\_\+mutex\+\_\+on} = false
\item 
const struct \textbf{ value\+\_\+string} \textbf{ loglevel\+\_\+strs} [$\,$]
\item 
static const struct \textbf{ log\+\_\+info\+\_\+cat} \textbf{ internal\+\_\+cat} [\textbf{ OSMO\+\_\+\+NUM\+\_\+\+DLIB}]
\item 
static const struct \textbf{ value\+\_\+string} \textbf{ level\+\_\+colors} [$\,$]
\end{DoxyCompactItemize}


\doxysubsection{Detailed Description}
Debugging/\+Logging support code. 

