\chapter{Log Tutorial}
\hypertarget{tutorial_log_page}{}\label{tutorial_log_page}\index{Log Tutorial@{Log Tutorial}}
\hypertarget{tutorial_log_page_tutorial_log_introduction}{}\doxysection{\texorpdfstring{Introduction}{Introduction}}\label{tutorial_log_page_tutorial_log_introduction}
The Eina Log module provides logging facilities for libraries and applications. It provides colored logging, basic logging levels (error, warning, debug, info, critical) and loggers -\/ called logging domains -\/ which will be covered in next sections.\hypertarget{tutorial_log_page_tutorial_log_basic_usage}{}\doxysection{\texorpdfstring{Basic Usage}{Basic Usage}}\label{tutorial_log_page_tutorial_log_basic_usage}
Log messages can be displayed using the following macros\+:

\begin{DoxyItemize}
\item \doxylink{group__Eina__Log__Group_ga2e33caeeeb6051526c01b7fea4d6c91b}{EINA\+\_\+\+LOG\+\_\+\+ERR()}, \item \doxylink{group__Eina__Log__Group_gafb145e82df0f9441244832c94e87a21b}{EINA\+\_\+\+LOG\+\_\+\+INFO()}, \item \doxylink{group__Eina__Log__Group_ga21c44f66537533db16ee8f475ae2ae70}{EINA\+\_\+\+LOG\+\_\+\+WARN()}, \item \doxylink{group__Eina__Log__Group_ga09b88349373c2158f988d72375af5849}{EINA\+\_\+\+LOG\+\_\+\+DBG()}.\end{DoxyItemize}
Here is an example\+:


\begin{DoxyCodeInclude}{0}
\DoxyCodeLine{\textcolor{comment}{//Compile\ with:}}
\DoxyCodeLine{\textcolor{comment}{//gcc\ -\/Wall\ -\/o\ eina\_log\_02\ eina\_log\_02.c\ \`{}pkg-\/config\ -\/-\/cflags\ -\/-\/libs\ eina`}}
\DoxyCodeLine{}
\DoxyCodeLine{\textcolor{preprocessor}{\#include\ <stdlib.h>}}
\DoxyCodeLine{\textcolor{preprocessor}{\#include\ <stdio.h>}}
\DoxyCodeLine{}
\DoxyCodeLine{\textcolor{preprocessor}{\#include\ <\mbox{\hyperlink{Eina_8h}{Eina.h}}>}}
\DoxyCodeLine{}
\DoxyCodeLine{\textcolor{keywordtype}{void}\ test(\textcolor{keywordtype}{int}\ i)}
\DoxyCodeLine{\{}
\DoxyCodeLine{\ \ \ \mbox{\hyperlink{group__Eina__Log__Group_ga09b88349373c2158f988d72375af5849}{EINA\_LOG\_DBG}}(\textcolor{stringliteral}{"{}Entering\ test"{}});}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \textcolor{keywordflow}{if}\ (i\ <\ 0)}
\DoxyCodeLine{\ \ \ \ \ \{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \mbox{\hyperlink{group__Eina__Log__Group_ga2e33caeeeb6051526c01b7fea4d6c91b}{EINA\_LOG\_ERR}}(\textcolor{stringliteral}{"{}Argument\ is\ negative"{}});}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \textcolor{keywordflow}{return};}
\DoxyCodeLine{\ \ \ \ \ \}}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \mbox{\hyperlink{group__Eina__Log__Group_gafb145e82df0f9441244832c94e87a21b}{EINA\_LOG\_INFO}}(\textcolor{stringliteral}{"{}argument\ non\ negative"{}});}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \mbox{\hyperlink{group__Eina__Log__Group_ga09b88349373c2158f988d72375af5849}{EINA\_LOG\_DBG}}(\textcolor{stringliteral}{"{}Exiting\ test"{}});}
\DoxyCodeLine{\}}
\DoxyCodeLine{}
\DoxyCodeLine{\textcolor{keywordtype}{int}\ main(\textcolor{keywordtype}{void})}
\DoxyCodeLine{\{}
\DoxyCodeLine{\ \ \ \textcolor{keywordflow}{if}\ (!\mbox{\hyperlink{group__Eina__Main__Group_ga81b8137665b8a4d2cb38ca50017d4c74}{eina\_init}}())}
\DoxyCodeLine{\ \ \ \ \ \{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ printf(\textcolor{stringliteral}{"{}log\ during\ the\ initialization\ of\ Eina\_Log\ module\(\backslash\)n"{}});}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \textcolor{keywordflow}{return}\ EXIT\_FAILURE;}
\DoxyCodeLine{\ \ \ \ \ \}}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \mbox{\hyperlink{group__Eina__Log__Group_ga1dc287505a8a9e4a4d6fa71994491b17}{eina\_log\_level\_set}}(\mbox{\hyperlink{group__Eina__Log__Group_gga326699509b2e7578ace7c0a15b4a8c1aafdc5a5cfb78f5e4d5851447ed798af50}{EINA\_LOG\_LEVEL\_DBG}});}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ test(-\/1);}
\DoxyCodeLine{\ \ \ test(0);}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \mbox{\hyperlink{group__Eina__Main__Group_ga5bf35513199d5220341437c05696285d}{eina\_shutdown}}();}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \textcolor{keywordflow}{return}\ EXIT\_SUCCESS;}
\DoxyCodeLine{\}}

\end{DoxyCodeInclude}


If you compiled Eina without debug mode, execution will yield only one log message, which is "{}argument is negative"{}.

Here we introduce the concept of logging domains (or loggers), which might already be familiar to readers. It is basically a way to separate a set of log messages into a context (e.\+g. a module) and provide a way of controlling this set as a whole.

For example, suppose you have 3 different modules in your application and you want to get logging only from one of them (e.\+g. create some sort of filter). For achieving that, all you need to do is create a logging domain for each module so that all logging inside a module can be considered as a whole.

Logging domains are specified by a name, color applied to the name and the level. The first two (name and color) are set through code, that is, inside your application/module/library.

The level is used for controlling which messages should appear. It specifies the lowest level that should be displayed (e.\+g. a message with level 11 being logged on a domain with level set to 10 would be displayed, while a message with level 9 wouldn\textquotesingle{}t).

The domain level is set during runtime (in contrast with the name and color) through the environment variable EINA\+\_\+\+LOG\+\_\+\+LEVELS. This variable expects a list in the form domain\+\_\+name1\+:level1,domain\+\_\+name2\+:level2,... . For example\+:

\begin{DoxyVerb}EINA_LOG_LEVELS=mymodule1:5,mymodule2:2,mymodule3:0 ./myapp\end{DoxyVerb}


This line would set mymodule1 level to 5, mymodule2 level to 2 and mymodule3 level to 0.

There\textquotesingle{}s also a global logger to which EINA\+\_\+\+LOG\+\_\+(\+ERR, DBG, INFO, CRIT, WARN) macros do log on. It is a logger that is created internally by Eina Log with an empty name and can be used for general logging (where logging domains do not apply).

Since this global logger doesn\textquotesingle{}t have a name, you can\textquotesingle{}t set its level through EINA\+\_\+\+LOG\+\_\+\+LEVELS variable. Here we introduce a second environment variable that is a bit more special\+: EINA\+\_\+\+LOG\+\_\+\+LEVEL.

This variable specifies the level of the global logging domain and the level of domains that haven\textquotesingle{}t been set through EINA\+\_\+\+LOG\+\_\+\+LEVELS. Here\textquotesingle{}s an example\+:

\begin{DoxyVerb}EINA_LOG_LEVEL=3 EINA_LOG_LEVELS=module1:10,module3:2 ./myapp\end{DoxyVerb}


Supposing you have modules named "{}module1"{}, "{}module2"{} and "{}module3"{}, this line would result in module1 with level 10, module2 with level 3 and module3 with level 2. Note that module2\textquotesingle{}s level wasn\textquotesingle{}t specified, so it\textquotesingle{}s level is set to the global level. This way we can easily apply filters to multiple domains with only one parameter (EINA\+\_\+\+LOG\+\_\+\+LEVEL=num).

The global level (EINA\+\_\+\+LOG\+\_\+\+LEVEL) can also be set through code, using \doxylink{group__Eina__Log__Group_ga1dc287505a8a9e4a4d6fa71994491b17}{eina\+\_\+log\+\_\+level\+\_\+set()} function.

While developing your libraries or applications, you may notice that EINA\+\_\+\+LOG\+\_\+\+DOM\+\_\+(\+ERR, DBG, INFO, CRIT, WARN) macros also print out messages from eina itself. Here we introduce another environment variable that is a bit more special\+: EINA\+\_\+\+LOG\+\_\+\+LEVELS\+\_\+\+GLOB.

This variable allows you to disable the logging of any/all code in eina itself. This is useful when developing your libraries or applications so that you can see your own domain\textquotesingle{}s messages easier without having to sift through a lot of internal eina debug messages. Here\textquotesingle{}s an example\+:

\begin{DoxyVerb}EINA_LOG_LEVEL=3 EINA_LOG_LEVELS_GLOB=eina_*:0 ./myapp\end{DoxyVerb}


This will disable eina\+\_\+log output from all internal eina code thus allowing you to see your own domain messages easier.\hypertarget{tutorial_log_page_tutorial_log_advanced_display}{}\doxysection{\texorpdfstring{Advanced usage of print callbacks}{Advanced usage of print callbacks}}\label{tutorial_log_page_tutorial_log_advanced_display}
The log module allows the user to change the way \doxylink{group__Eina__Log__Group_ga6d455dd27e2148919e225aec3a159c0c}{eina\+\_\+log\+\_\+print()} displays the messages. It suffices to pass to \doxylink{group__Eina__Log__Group_ga163f303fe131ed5c15dc5754945d2f62}{eina\+\_\+log\+\_\+print\+\_\+cb\+\_\+set()} the function used to display the message. That function must be of type \doxylink{group__Eina__Log__Group_ga76501a2d10e374980c4012664e4ca96f}{Eina\+\_\+\+Log\+\_\+\+Print\+\_\+\+Cb}. As a custom data can be passed to that callback, powerful display messages can be displayed.

It is suggested to not use {\bfseries{FILE}}, {\bfseries{func}} or {\bfseries{LINE}} when writing that callback, but when defining macros (like \doxylink{group__Eina__Log__Group_ga2e33caeeeb6051526c01b7fea4d6c91b}{EINA\+\_\+\+LOG\+\_\+\+ERR()} and other macros).

Here is an example of custom callback, whose behavior can be changed at runtime\+:


\begin{DoxyCodeInclude}{0}
\DoxyCodeLine{\textcolor{comment}{//Compile\ with:}}
\DoxyCodeLine{\textcolor{comment}{//gcc\ -\/Wall\ -\/o\ eina\_log\_03\ eina\_log\_03.c\ \`{}pkg-\/config\ -\/-\/cflags\ -\/-\/libs\ eina`}}
\DoxyCodeLine{}
\DoxyCodeLine{\textcolor{preprocessor}{\#include\ <stdlib.h>}}
\DoxyCodeLine{\textcolor{preprocessor}{\#include\ <stdio.h>}}
\DoxyCodeLine{}
\DoxyCodeLine{\textcolor{preprocessor}{\#include\ <\mbox{\hyperlink{Eina_8h}{Eina.h}}>}}
\DoxyCodeLine{}
\DoxyCodeLine{\textcolor{preprocessor}{\#define\ log(fmt,\ ...)\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \(\backslash\)}}
\DoxyCodeLine{\textcolor{preprocessor}{\ \ \ eina\_log\_print(EINA\_LOG\_LEVEL\_ERR,\ \_\_FILE\_\_,\ \_\_func\_\_,\ \_\_LINE\_\_,\ fmt,\ \#\#\_\_VA\_ARGS\_\_)}}
\DoxyCodeLine{}
\DoxyCodeLine{\textcolor{keyword}{typedef}\ \textcolor{keyword}{struct\ }\_Data\ Data;}
\DoxyCodeLine{}
\DoxyCodeLine{\textcolor{keyword}{struct\ }\_Data}
\DoxyCodeLine{\{}
\DoxyCodeLine{\ \ \ \textcolor{keywordtype}{int}\ to\_stderr;}
\DoxyCodeLine{\};}
\DoxyCodeLine{}
\DoxyCodeLine{\textcolor{keywordtype}{void}\ print\_cb(\textcolor{keyword}{const}\ \mbox{\hyperlink{struct__Eina__Log__Domain}{Eina\_Log\_Domain}}\ *domain,}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \mbox{\hyperlink{group__Eina__Log__Group_ga5c0cd3a8463b76bb855805b70f58c7dd}{Eina\_Log\_Level}}\ level\ \mbox{\hyperlink{group__Eina__Types__Group_ga82d751be730f849719ca292f9558be87}{EINA\_UNUSED}},}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \textcolor{keyword}{const}\ \textcolor{keywordtype}{char}\ *file,}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \textcolor{keyword}{const}\ \textcolor{keywordtype}{char}\ *fnc,}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \textcolor{keywordtype}{int}\ line,}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \textcolor{keyword}{const}\ \textcolor{keywordtype}{char}\ *fmt,}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \textcolor{keywordtype}{void}\ *data,}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ va\_list\ args)}
\DoxyCodeLine{\{}
\DoxyCodeLine{\ \ \ Data\ *d;}
\DoxyCodeLine{\ \ \ FILE\ *output;}
\DoxyCodeLine{\ \ \ \textcolor{keywordtype}{char}\ *str;}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ d\ =\ (Data*)data;}
\DoxyCodeLine{\ \ \ \textcolor{keywordflow}{if}\ (d-\/>to\_stderr)}
\DoxyCodeLine{\ \ \ \ \ \{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ output\ =\ stderr;}
\DoxyCodeLine{\ \ \ \ \ \ \ \ str\ =\ \textcolor{stringliteral}{"{}stderr"{}};}
\DoxyCodeLine{\ \ \ \ \}}
\DoxyCodeLine{\ \ \ \textcolor{keywordflow}{else}}
\DoxyCodeLine{\ \ \ \ \ \{}
\DoxyCodeLine{\ \ \ \ \ \ \ output\ =\ stdout;}
\DoxyCodeLine{\ \ \ \ \ \ \ \ str\ =\ \textcolor{stringliteral}{"{}stdout"{}};}
\DoxyCodeLine{\ \ \ \ \ \}}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ fprintf(output,\ \textcolor{stringliteral}{"{}\%s:\%s:\%s\ (\%d)\ \%s:\ "{}},}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ domain-\/>\mbox{\hyperlink{struct__Eina__Log__Domain_adac00ef51a0009e12583ca5932275f2e}{domain\_str}},\ file,\ fnc,\ line,\ str);}
\DoxyCodeLine{\ \ \ vfprintf(output,\ fmt,\ args);}
\DoxyCodeLine{\ \ \ putc(\textcolor{charliteral}{'\(\backslash\)n'},\ output);}
\DoxyCodeLine{\}}
\DoxyCodeLine{}
\DoxyCodeLine{\textcolor{keywordtype}{void}\ test(Data\ *data,\ \textcolor{keywordtype}{int}\ i)}
\DoxyCodeLine{\{}
\DoxyCodeLine{\ \ \ \textcolor{keywordflow}{if}\ (i\ <\ 0)}
\DoxyCodeLine{\ \ \ \ \ \ data-\/>to\_stderr\ =\ 0;}
\DoxyCodeLine{\ \ \ \textcolor{keywordflow}{else}}
\DoxyCodeLine{\ \ \ \ \ \ data-\/>to\_stderr\ =\ 1;}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \mbox{\hyperlink{group__Eina__Log__Group_gafb145e82df0f9441244832c94e87a21b}{EINA\_LOG\_INFO}}(\textcolor{stringliteral}{"{}Log\ message..."{}});}
\DoxyCodeLine{\}}
\DoxyCodeLine{}
\DoxyCodeLine{\textcolor{keywordtype}{int}\ main(\textcolor{keywordtype}{void})}
\DoxyCodeLine{\{}
\DoxyCodeLine{\ \ \ Data\ data;}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \textcolor{keywordflow}{if}\ (!\mbox{\hyperlink{group__Eina__Main__Group_ga81b8137665b8a4d2cb38ca50017d4c74}{eina\_init}}())}
\DoxyCodeLine{\ \ \ \ \ \{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ printf(\textcolor{stringliteral}{"{}log\ during\ the\ initialization\ of\ Eina\_Log\ module\(\backslash\)n"{}});}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \textcolor{keywordflow}{return}\ EXIT\_FAILURE;}
\DoxyCodeLine{\ \ \ \ \ \}}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \mbox{\hyperlink{group__Eina__Log__Group_ga163f303fe131ed5c15dc5754945d2f62}{eina\_log\_print\_cb\_set}}(print\_cb,\ \&data);}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ test(\&data,\ -\/1);}
\DoxyCodeLine{\ \ \ test(\&data,\ 0);}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \mbox{\hyperlink{group__Eina__Main__Group_ga5bf35513199d5220341437c05696285d}{eina\_shutdown}}();}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \textcolor{keywordflow}{return}\ EXIT\_SUCCESS;}
\DoxyCodeLine{\}}

\end{DoxyCodeInclude}
 