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

\begin{DoxyItemize}
\item \hyperlink{group__Eina__Log__Group_ga2e33caeeeb6051526c01b7fea4d6c91b}{E\+I\+N\+A\+\_\+\+L\+O\+G\+\_\+\+E\+R\+R()}, \item \hyperlink{group__Eina__Log__Group_gafb145e82df0f9441244832c94e87a21b}{E\+I\+N\+A\+\_\+\+L\+O\+G\+\_\+\+I\+N\+F\+O()}, \item \hyperlink{group__Eina__Log__Group_ga21c44f66537533db16ee8f475ae2ae70}{E\+I\+N\+A\+\_\+\+L\+O\+G\+\_\+\+W\+A\+R\+N()}, \item \hyperlink{group__Eina__Log__Group_ga09b88349373c2158f988d72375af5849}{E\+I\+N\+A\+\_\+\+L\+O\+G\+\_\+\+D\+B\+G()}.\end{DoxyItemize}
Here is an example\+:


\begin{DoxyCodeInclude}
\textcolor{comment}{//Compile with:}
\textcolor{comment}{//gcc -Wall -o eina\_log\_02 eina\_log\_02.c `pkg-config --cflags --libs eina`}

\textcolor{preprocessor}{#include <stdlib.h>}
\textcolor{preprocessor}{#include <stdio.h>}

\textcolor{preprocessor}{#include <\hyperlink{Eina_8h}{Eina.h}>}

\textcolor{keywordtype}{void} test(\textcolor{keywordtype}{int} i)
\{
   \hyperlink{group__Eina__Log__Group_ga09b88349373c2158f988d72375af5849}{EINA\_LOG\_DBG}(\textcolor{stringliteral}{"Entering test"});

   \textcolor{keywordflow}{if} (i < 0)
     \{
         \hyperlink{group__Eina__Log__Group_ga2e33caeeeb6051526c01b7fea4d6c91b}{EINA\_LOG\_ERR}(\textcolor{stringliteral}{"Argument is negative"});
         \textcolor{keywordflow}{return};
     \}

   \hyperlink{group__Eina__Log__Group_gafb145e82df0f9441244832c94e87a21b}{EINA\_LOG\_INFO}(\textcolor{stringliteral}{"argument non negative"});

   \hyperlink{group__Eina__Log__Group_ga09b88349373c2158f988d72375af5849}{EINA\_LOG\_DBG}(\textcolor{stringliteral}{"Exiting test"});
\}

\textcolor{keywordtype}{int} main(\textcolor{keywordtype}{void})
\{
   \textcolor{keywordflow}{if} (!\hyperlink{group__Eina__Main__Group_gabf448ada5bc81a07342b66c6f818ee5e}{eina\_init}())
     \{
         printf(\textcolor{stringliteral}{"log during the initialization of Eina\_Log module\(\backslash\)n"});
         \textcolor{keywordflow}{return} EXIT\_FAILURE;
     \}

   test(-1);
   test(0);

   \hyperlink{group__Eina__Main__Group_ga6741fcaba116e31e96ce14dcfa03f568}{eina\_shutdown}();

   \textcolor{keywordflow}{return} EXIT\_SUCCESS;
\}
\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 on 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 \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}{}\section{Advanced usage of print callbacks}\label{tutorial_log_page_tutorial_log_advanced_display}
The log module allows the user to change the way \hyperlink{group__Eina__Log__Group_ga4cca81b7002645e5550283f687b903db}{eina\+\_\+log\+\_\+print()} displays the messages. It suffices to pass to \hyperlink{group__Eina__Log__Group_ga50184735e08f530d4139c28fcdb02fbb}{eina\+\_\+log\+\_\+print\+\_\+cb\+\_\+set()} the function used to display the message. That function must be of type \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 \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}
\textcolor{comment}{//Compile with:}
\textcolor{comment}{//gcc -Wall -o eina\_log\_03 eina\_log\_03.c `pkg-config --cflags --libs eina`}

\textcolor{preprocessor}{#include <stdlib.h>}
\textcolor{preprocessor}{#include <stdio.h>}

\textcolor{preprocessor}{#include <\hyperlink{Eina_8h}{Eina.h}>}

\textcolor{preprocessor}{#define log(fmt, ...)                                    \(\backslash\)}
\textcolor{preprocessor}{   eina\_log\_print(EINA\_LOG\_LEVEL\_ERR, \_\_FILE\_\_, \_\_FUNCTION\_\_, \_\_LINE\_\_, fmt, ##\_\_VA\_ARGS\_\_)}

\textcolor{keyword}{typedef} \textcolor{keyword}{struct }\_Data Data;

\textcolor{keyword}{struct }\_Data
\{
   \textcolor{keywordtype}{int} to\_stderr;
\};

\textcolor{keywordtype}{void} print\_cb(\textcolor{keyword}{const} \hyperlink{struct__Eina__Log__Domain}{Eina\_Log\_Domain} *domain,
              \hyperlink{group__Eina__Log__Group_ga5c0cd3a8463b76bb855805b70f58c7dd}{Eina\_Log\_Level} level EINA\_UNUSED,
              \textcolor{keyword}{const} \textcolor{keywordtype}{char} *file,
              \textcolor{keyword}{const} \textcolor{keywordtype}{char} *fnc,
              \textcolor{keywordtype}{int} line,
              \textcolor{keyword}{const} \textcolor{keywordtype}{char} *fmt,
              \textcolor{keywordtype}{void} *data,
              va\_list args)
\{
   Data *d;
   FILE *output;
   \textcolor{keywordtype}{char} *str;

   d = (Data*)data;
   \textcolor{keywordflow}{if} (d->to\_stderr)
     \{
        output = stderr;
        str = \textcolor{stringliteral}{"stderr"};
    \}
   \textcolor{keywordflow}{else}
     \{
       output = stdout;
        str = \textcolor{stringliteral}{"stdout"};
     \}

   fprintf(output, \textcolor{stringliteral}{"%s:%s:%s (%d) %s: "},
           domain->\hyperlink{struct__Eina__Log__Domain_adac00ef51a0009e12583ca5932275f2e}{domain\_str}, file, fnc, line, str);
   vfprintf(output, fmt, args);
   putc(\textcolor{charliteral}{'\(\backslash\)n'}, output);
\}

\textcolor{keywordtype}{void} test(Data *data, \textcolor{keywordtype}{int} i)
\{
   \textcolor{keywordflow}{if} (i < 0)
      data->to\_stderr = 0;
   \textcolor{keywordflow}{else}
      data->to\_stderr = 1;

   \hyperlink{group__Eina__Log__Group_gafb145e82df0f9441244832c94e87a21b}{EINA\_LOG\_INFO}(\textcolor{stringliteral}{"Log message..."});
\}

\textcolor{keywordtype}{int} main(\textcolor{keywordtype}{void})
\{
   Data data;

   \textcolor{keywordflow}{if} (!\hyperlink{group__Eina__Main__Group_gabf448ada5bc81a07342b66c6f818ee5e}{eina\_init}())
     \{
        printf(\textcolor{stringliteral}{"log during the initialization of Eina\_Log module\(\backslash\)n"});
        \textcolor{keywordflow}{return} EXIT\_FAILURE;
     \}

   \hyperlink{group__Eina__Log__Group_ga50184735e08f530d4139c28fcdb02fbb}{eina\_log\_print\_cb\_set}(print\_cb, &data);

   test(&data, -1);
   test(&data, 0);

   \hyperlink{group__Eina__Main__Group_ga6741fcaba116e31e96ce14dcfa03f568}{eina\_shutdown}();

   \textcolor{keywordflow}{return} EXIT\_SUCCESS;
\}
\end{DoxyCodeInclude}
 