\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'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\+L\+S. 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'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't have a name, you can't set its level through E\+I\+N\+A\+\_\+\+L\+O\+G\+\_\+\+L\+E\+V\+E\+L\+S variable. Here we introduce a second environment variable that is a bit more special\+: E\+I\+N\+A\+\_\+\+L\+O\+G\+\_\+\+L\+E\+V\+E\+L.

This variable specifies the level of the global logging domain and the level of domains that haven't been set through E\+I\+N\+A\+\_\+\+L\+O\+G\+\_\+\+L\+E\+V\+E\+L\+S. Here'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's level wasn't specified, so it'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\+E\+L=num).

The global level (E\+I\+N\+A\+\_\+\+L\+O\+G\+\_\+\+L\+E\+V\+E\+L) 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\+O\+B.

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's messages easier without having to sift through a lot of internal eina debug messages. Here'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\+L\+E}, {\bfseries F\+U\+N\+C\+T\+I\+O\+N} or {\bfseries L\+I\+N\+E} 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}
 