\hypertarget{tutorial_log_page_tutorial_log_introduction}{}\doxysection{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{Basic Usage}\label{tutorial_log_page_tutorial_log_basic_usage}
Log messages can be displayed using the following macros\+:

\begin{DoxyItemize}
\item \mbox{\hyperlink{group__Eina__Log__Group_ga2e33caeeeb6051526c01b7fea4d6c91b}{EINA\+\_\+\+LOG\+\_\+\+ERR()}}, \item \mbox{\hyperlink{group__Eina__Log__Group_gafb145e82df0f9441244832c94e87a21b}{EINA\+\_\+\+LOG\+\_\+\+INFO()}}, \item \mbox{\hyperlink{group__Eina__Log__Group_ga21c44f66537533db16ee8f475ae2ae70}{EINA\+\_\+\+LOG\+\_\+\+WARN()}}, \item \mbox{\hyperlink{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_gafee4bfc0e509b6ffed6598edf6f4b3de}{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_ga3588dded50cc324ab6f84da2f328bd8e}{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_ga2c8b4020427108a30c44707af22c99d3}{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 \char`\"{}argument is negative\char`\"{}.

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 \char`\"{}module1\char`\"{}, \char`\"{}module2\char`\"{} and \char`\"{}module3\char`\"{}, 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 \mbox{\hyperlink{group__Eina__Log__Group_ga3588dded50cc324ab6f84da2f328bd8e}{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{Advanced usage of print callbacks}\label{tutorial_log_page_tutorial_log_advanced_display}
The log module allows the user to change the way \mbox{\hyperlink{group__Eina__Log__Group_ga2ad47c77225cbcf8d35840547b5bbbe4}{eina\+\_\+log\+\_\+print()}} displays the messages. It suffices to pass to \mbox{\hyperlink{group__Eina__Log__Group_gac7291079db979a0195d62d5526b27c30}{eina\+\_\+log\+\_\+print\+\_\+cb\+\_\+set()}} the function used to display the message. That function must be of type \mbox{\hyperlink{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 \mbox{\hyperlink{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_gafee4bfc0e509b6ffed6598edf6f4b3de}{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_gac7291079db979a0195d62d5526b27c30}{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_ga2c8b4020427108a30c44707af22c99d3}{eina\_shutdown}}();}
\DoxyCodeLine{}
\DoxyCodeLine{   \textcolor{keywordflow}{return} EXIT\_SUCCESS;}
\DoxyCodeLine{\}}

\end{DoxyCodeInclude}
 