\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}{E\+I\+N\+A\+\_\+\+L\+O\+G\+\_\+\+E\+R\+R()}}, \item \mbox{\hyperlink{group__Eina__Log__Group_gafb145e82df0f9441244832c94e87a21b}{E\+I\+N\+A\+\_\+\+L\+O\+G\+\_\+\+I\+N\+F\+O()}}, \item \mbox{\hyperlink{group__Eina__Log__Group_ga21c44f66537533db16ee8f475ae2ae70}{E\+I\+N\+A\+\_\+\+L\+O\+G\+\_\+\+W\+A\+R\+N()}}, \item \mbox{\hyperlink{group__Eina__Log__Group_ga09b88349373c2158f988d72375af5849}{E\+I\+N\+A\+\_\+\+L\+O\+G\+\_\+\+D\+B\+G()}}.\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_ga018457ec82c2e428600d1023d4b92749}{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 E\+I\+N\+A\+\_\+\+L\+O\+G\+\_\+\+L\+E\+V\+E\+LS. 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 E\+I\+N\+A\+\_\+\+L\+O\+G\+\_\+(\+E\+R\+R, D\+B\+G, I\+N\+F\+O, C\+R\+I\+T, W\+A\+R\+N) 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 E\+I\+N\+A\+\_\+\+L\+O\+G\+\_\+\+L\+E\+V\+E\+LS variable. Here we introduce a second environment variable that is a bit more special\+: E\+I\+N\+A\+\_\+\+L\+O\+G\+\_\+\+L\+E\+V\+EL.

This variable specifies the level of the global logging domain and the level of domains that haven\textquotesingle{}t been set through E\+I\+N\+A\+\_\+\+L\+O\+G\+\_\+\+L\+E\+V\+E\+LS. 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 (E\+I\+N\+A\+\_\+\+L\+O\+G\+\_\+\+L\+E\+V\+EL=num).

The global level (E\+I\+N\+A\+\_\+\+L\+O\+G\+\_\+\+L\+E\+V\+EL) can also be set through code, using \mbox{\hyperlink{group__Eina__Log__Group_ga018457ec82c2e428600d1023d4b92749}{eina\+\_\+log\+\_\+level\+\_\+set()}} function.

While developing your libraries or applications, you may notice that E\+I\+N\+A\+\_\+\+L\+O\+G\+\_\+\+D\+O\+M\+\_\+(\+E\+R\+R, D\+B\+G, I\+N\+F\+O, C\+R\+I\+T, W\+A\+R\+N) macros also print out messages from eina itself. Here we introduce another environment variable that is a bit more special\+: E\+I\+N\+A\+\_\+\+L\+O\+G\+\_\+\+L\+E\+V\+E\+L\+S\+\_\+\+G\+L\+OB.

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_ga4cca81b7002645e5550283f687b903db}{eina\+\_\+log\+\_\+print()}} displays the messages. It suffices to pass to \mbox{\hyperlink{group__Eina__Log__Group_ga50184735e08f530d4139c28fcdb02fbb}{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{F\+I\+LE}}, {\bfseries{F\+U\+N\+C\+T\+I\+ON}} or {\bfseries{L\+I\+NE}} when writing that callback, but when defining macros (like \mbox{\hyperlink{group__Eina__Log__Group_ga2e33caeeeb6051526c01b7fea4d6c91b}{E\+I\+N\+A\+\_\+\+L\+O\+G\+\_\+\+E\+R\+R()}} 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\_\_, \_\_FUNCTION\_\_, \_\_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_ga50184735e08f530d4139c28fcdb02fbb}{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}
 