@srcdir@/gtut-tour-3-args.doc \
@srcdir@/gtut-tour-4-callback.doc \
@srcdir@/gtut-tour-5-globals.doc \
+ @srcdir@/gtut-tour-6-logs.doc \
\
./logcategories.doc \
\
_5-globals_client.c
_5-globals_server.c
_5-globals_simulator.c
+
+6-logs.mk
+6-logs.trace
+6-logs_client
+6-logs_server
+6-logs_simulator
+_6-logs_client.c
+_6-logs_server.c
+_6-logs_simulator.c
$ ./test_client
-[blaise:client:(6328) 0.000004] gras/gras.c:79: [gras/INFO] Exiting GRAS
+[blaise:client:(3539) 0.000004] gras/gras.c:79: [gras/INFO] Exiting GRAS
$ ./test_server
-[blaise:server:(6331) 0.000005] gras/gras.c:79: [gras/INFO] Exiting GRAS
+[blaise:server:(3542) 0.000004] gras/gras.c:79: [gras/INFO] Exiting GRAS
+$
$ ./test_simulator platform.xml test.xml
[Jacquelin:server:(1) 0.000000] gras/gras.c:79: [gras/INFO] Exiting GRAS
[Boivin:client:(2) 0.000000] gras/gras.c:79: [gras/INFO] Exiting GRAS
$ ./test_server 12345 & ./test_client 127.0.0.1 12345
Client ready; listening on 1024
That's it, we sent the data to the server on 127.0.0.1
-[blaise:client:(6454) 0.000005] gras/gras.c:79: [gras/INFO] Exiting GRAS
+[blaise:client:(3668) 0.000005] gras/gras.c:79: [gras/INFO] Exiting GRAS
Cool, we received the message from 127.0.0.1:1024.
-[blaise:server:(6452) 0.000004] gras/gras.c:79: [gras/INFO] Exiting GRAS
+[blaise:server:(3666) 0.000005] gras/gras.c:79: [gras/INFO] Exiting GRAS
+$
$ ./test_simulator platform.xml test.xml
Client ready; listening on 1024
That's it, we sent the data to the server on Jacquelin
-$ ./test_server 12345 & ./test_client 127.0.0.1 12345
+$ ./test_server 23451 & ./test_client 127.0.0.1 23451
Client ready; listening on 1024
That's it, we sent the data to the server on 127.0.0.1
-[blaise:client:(7454) 0.000004] gras/gras.c:79: [gras/INFO] Exiting GRAS
+[blaise:client:(3770) 0.000005] gras/gras.c:79: [gras/INFO] Exiting GRAS
Cool, we received the message from 127.0.0.1:1024.
-[blaise:server:(7452) 0.000004] gras/gras.c:79: [gras/INFO] Exiting GRAS
+[blaise:server:(3768) 0.000004] gras/gras.c:79: [gras/INFO] Exiting GRAS
+$
$ ./test_simulator platform.xml test.xml
Client ready; listening on 1024
That's it, we sent the data to the server on Jacquelin
typedef struct {
int killed;
-} *server_data_t;
+} server_data_t;
int server_kill_cb(gras_msg_cb_ctx_t ctx, void *payload) {
int server(int argc, char *argv[]) {
gras_socket_t mysock; /* socket on which I listen */
- server_data_t globals;
+ server_data_t *globals;
gras_init(&argc,argv);
- globals=gras_userdata_new(server_data_t);
+ globals=gras_userdata_new(server_data_t*);
globals->killed=0;
gras_msgtype_declare("hello", NULL);
we sent the data to the server on 127.0.0.1. Let's do it again for fun
Ok. Enough. Have a rest, and then kill the server
Cool, we received the message from 127.0.0.1:1024.
-[blaise:client:(18581) 0.000005] gras/gras.c:79: [gras/INFO] Exiting GRAS
+[blaise:client:(3874) 0.000005] gras/gras.c:79: [gras/INFO] Exiting GRAS
Cool, we received the message from 127.0.0.1:1024.
Argh, killed by 127.0.0.1:1024! Bye folks...
+[blaise:server:(3872) 0.000005] gras/gras.c:79: [gras/INFO] Exiting GRAS
+$
$ ./test_simulator platform.xml test.xml
Client ready; listening on 1024
we sent the data to the server on Jacquelin. Let's do it again for fun
Cool, we received the message from Boivin:1024.
[Boivin:client:(2) 0.000000] gras/gras.c:79: [gras/INFO] Exiting GRAS
Argh, killed by Boivin:1024! Bye folks...
-[0.000000] msg/global.c:478: [msg_kernel/INFO] Oops ! Deadlock or code not perfectly clean.
-[0.000000] msg/global.c:293: [msg_kernel/INFO] MSG: 1 processes are still running, waiting for something.
-[0.000000] msg/global.c:295: [msg_kernel/INFO] MSG: <process>(<pid>) on <host>: <status>.
-[0.000000] msg/global.c:309: [msg_kernel/INFO] MSG: server(1) on Jacquelin: [blocked] Listening on channel 0
-[0.000000] msg/global.c:486: [msg_kernel/INFO] Return a Warning.
+[Jacquelin:server:(1) 0.000000] gras/gras.c:79: [gras/INFO] Exiting GRAS
+[0.000000] msg/global.c:475: [msg_kernel/INFO] Congratulations ! Simulation terminated : all process are over
$
--- /dev/null
+#include <gras.h>
+
+XBT_LOG_NEW_DEFAULT_CATEGORY(test,"My little example");
+
+typedef struct {
+ int killed;
+} server_data_t;
+
+
+int server_kill_cb(gras_msg_cb_ctx_t ctx, void *payload) {
+ gras_socket_t client = gras_msg_cb_ctx_from(ctx);
+ server_data_t *globals=(server_data_t*)gras_userdata_get();
+
+ CRITICAL2("Argh, killed by %s:%d! Bye folks...",
+ gras_socket_peer_name(client), gras_socket_peer_port(client));
+
+ globals->killed = 1;
+
+ return 1;
+} /* end_of_kill_callback */
+
+int server_hello_cb(gras_msg_cb_ctx_t ctx, void *payload) {
+ gras_socket_t client = gras_msg_cb_ctx_from(ctx);
+
+ INFO2("Cool, we received the message from %s:%d.",
+ gras_socket_peer_name(client), gras_socket_peer_port(client));
+
+ return 1;
+} /* end_of_hello_callback */
+
+int server(int argc, char *argv[]) {
+ gras_socket_t mysock; /* socket on which I listen */
+ server_data_t *globals;
+
+ gras_init(&argc,argv);
+
+ globals=gras_userdata_new(server_data_t*);
+ globals->killed=0;
+
+ gras_msgtype_declare("hello", NULL);
+ gras_msgtype_declare("kill", NULL);
+ mysock = gras_socket_server(atoi(argv[1]));
+
+ gras_cb_register(gras_msgtype_by_name("hello"),&server_hello_cb);
+ gras_cb_register(gras_msgtype_by_name("kill"),&server_kill_cb);
+
+ while (!globals->killed) {
+ gras_msg_handle(-1); /* blocking */
+ }
+
+ gras_exit();
+ return 0;
+}
+
+int client(int argc, char *argv[]) {
+ gras_socket_t mysock; /* socket on which I listen */
+ gras_socket_t toserver; /* socket used to write to the server */
+
+ gras_init(&argc,argv);
+
+ gras_msgtype_declare("hello", NULL);
+ gras_msgtype_declare("kill", NULL);
+ mysock = gras_socket_server_range(1024, 10000, 0, 0);
+
+ VERB1("Client ready; listening on %d", gras_socket_my_port(mysock));
+
+ gras_os_sleep(1.5); /* sleep 1 second and half */
+ toserver = gras_socket_client(argv[1], atoi(argv[2]));
+
+ gras_msg_send(toserver,gras_msgtype_by_name("hello"), NULL);
+ INFO1("we sent the data to the server on %s. Let's do it again for fun", gras_socket_peer_name(toserver));
+ gras_msg_send(toserver,gras_msgtype_by_name("hello"), NULL);
+
+ INFO0("Ok. Enough. Have a rest, and then kill the server");
+ gras_os_sleep(5); /* sleep 1 second and half */
+ gras_msg_send(toserver,gras_msgtype_by_name("kill"), NULL);
+
+ gras_exit();
+ return 0;
+}
--- /dev/null
+$ ./test_server 12345 & ./test_client 127.0.0.1 12345
+[blaise:client:(15633) 0.000005] test.c:71: [test/INFO] we sent the data to the server on 127.0.0.1. Let's do it again for fun
+[blaise:client:(15633) 0.000071] test.c:74: [test/INFO] Ok. Enough. Have a rest, and then kill the server
+[blaise:client:(15633) 5.008669] gras/gras.c:79: [gras/INFO] Exiting GRAS
+[blaise:server:(15630) 0.000005] test.c:26: [test/INFO] Cool, we received the message from 127.0.0.1:1024.
+[blaise:server:(15630) 5.008181] test.c:26: [test/INFO] Cool, we received the message from 127.0.0.1:1024.
+[blaise:server:(15630) 5.008226] test.c:15: [test/CRITICAL] Argh, killed by 127.0.0.1:1024! Bye folks...
+[blaise:server:(15630) 5.008245] gras/gras.c:79: [gras/INFO] Exiting GRAS
+$
+$ ./test_simulator platform.xml test.xml
+[Boivin:client:(2) 0.000000] test.c:71: [test/INFO] we sent the data to the server on Jacquelin. Let's do it again for fun
+[Jacquelin:server:(1) 0.000000] test.c:26: [test/INFO] Cool, we received the message from Boivin:1024.
+[Boivin:client:(2) 0.000537] test.c:74: [test/INFO] Ok. Enough. Have a rest, and then kill the server
+[Jacquelin:server:(1) 0.000537] test.c:26: [test/INFO] Cool, we received the message from Boivin:1024.
+[Boivin:client:(2) 5.001074] gras/gras.c:79: [gras/INFO] Exiting GRAS
+[Jacquelin:server:(1) 5.001074] test.c:15: [test/CRITICAL] Argh, killed by Boivin:1024! Bye folks...
+[Jacquelin:server:(1) 5.001074] gras/gras.c:79: [gras/INFO] Exiting GRAS
+[5.001074] msg/global.c:475: [msg_kernel/INFO] Congratulations ! Simulation terminated : all process are over
+$
--- /dev/null
+$ ./test_server 12345 --gras-log=root.thres=error & ./test_client 127.0.0.1 12345 --gras-log=root.thres=error
+[blaise:server:(15511) 0.000005] test.c:15: [test/CRITICAL] Argh, killed by 127.0.0.1:1024! Bye folks...
+$
+$ ./test_simulator platform.xml test.xml --gras-log=root.thres=error
+[Jacquelin:server:(1) 0.000000] test.c:15: [test/CRITICAL] Argh, killed by Boivin:1024! Bye folks...
+$
--- /dev/null
+$ ./test_server 12345 --gras-log=test.thres=verbose & ./test_client 127.0.0.1 12345 --gras-log=test.thres=verbose
+[blaise:client:(12057) 0.000005] test.c:65: [test/VERBOSE] Client ready; listening on 1024
+[blaise:client:(12057) 1.506727] test.c:71: [test/INFO] we sent the data to the server on 127.0.0.1. Let's do it again for fun
+[blaise:client:(12057) 1.506758] test.c:74: [test/INFO] Ok. Enough. Have a rest, and then kill the server
+[blaise:client:(12057) 6.735174] gras/gras.c:79: [gras/INFO] Exiting GRAS
+[blaise:server:(12054) 0.000004] test.c:26: [test/INFO] Cool, we received the message from 127.0.0.1:1024.
+[blaise:server:(12054) 5.228655] test.c:26: [test/INFO] Cool, we received the message from 127.0.0.1:1024.
+[blaise:server:(12054) 5.228698] test.c:15: [test/CRITICAL] Argh, killed by 127.0.0.1:1024! Bye folks...
+[blaise:server:(12054) 5.228716] gras/gras.c:79: [gras/INFO] Exiting GRAS
+$
+$ ./test_simulator platform.xml test.xml --gras-log=test.thres=verbose
+[Boivin:client:(2) 0.000000] test.c:65: [test/VERBOSE] Client ready; listening on 1024
+[Boivin:client:(2) 1.500537] test.c:71: [test/INFO] we sent the data to the server on Jacquelin. Let's do it again for fun
+[Jacquelin:server:(1) 1.500537] test.c:26: [test/INFO] Cool, we received the message from Boivin:1024.
+[Boivin:client:(2) 1.501074] test.c:74: [test/INFO] Ok. Enough. Have a rest, and then kill the server
+[Jacquelin:server:(1) 1.501074] test.c:26: [test/INFO] Cool, we received the message from Boivin:1024.
+[Boivin:client:(2) 6.501611] gras/gras.c:79: [gras/INFO] Exiting GRAS
+[Jacquelin:server:(1) 6.501611] test.c:15: [test/CRITICAL] Argh, killed by Boivin:1024! Bye folks...
+[Jacquelin:server:(1) 6.501611] gras/gras.c:79: [gras/INFO] Exiting GRAS
+[6.501611] msg/global.c:475: [msg_kernel/INFO] Congratulations ! Simulation terminated : all process are over
+$
export LD_LIBRARY_PATH=$(GRAS_ROOT)/lib
all: 1-bones.output 2-simple.output 3-args.output 4-callback.output \
- 5-globals.output
+ 5-globals.output 6-logs.output
veryclean: clean
- rm *.output
+ rm *.output*
# Lesson 1: simple bones of project
########################################
./1-bones_client >> $@ 2>&1
echo '$$ ./test_server' >> $@
./1-bones_server >> $@ 2>&1
+ echo '$$' >> $@
echo '$$ ./test_simulator platform.xml test.xml' >> $@
./1-bones_simulator gtut-platform.xml test.xml >> $@ 2>&1
echo '$$' >> $@
./3-args_server 12345 >> $@ 2>&1&
./3-args_client 127.0.0.1 12345 >> $@ 2>&1
sleep 1
+ echo '$$' >> $@
echo '$$ ./test_simulator platform.xml test.xml' >> $@
./3-args_simulator gtut-platform.xml 3-args.xml >> $@ 2>&1
echo '$$' >> $@
+ killall 3-args_server 3-args_client 2>/dev/null || true
3-args_client 3-args_server 3-args_simulator: _3-args_client.c _3-args_server.c _3-args_simulator.c
make -f 3-args.mk
########################################
4-callback.output: 4-callback_client 4-callback_server 4-callback_simulator
- echo '$$ ./test_server 12345 & ./test_client 127.0.0.1 12345' > $@
- ./4-callback_server 12345 >> $@ 2>&1&
- ./4-callback_client 127.0.0.1 12345 >> $@ 2>&1
+ echo '$$ ./test_server 23451 & ./test_client 127.0.0.1 23451' > $@
+ ./4-callback_server 23451 >> $@ 2>&1&
+ ./4-callback_client 127.0.0.1 23451 >> $@ 2>&1
sleep 1
+ echo '$$' >> $@
echo '$$ ./test_simulator platform.xml test.xml' >> $@
./4-callback_simulator gtut-platform.xml 3-args.xml >> $@ 2>&1
- echo '$$' >> $@
+ echo '$$' >> $@
+ killall 4-callback_server 4-callback_client 2>/dev/null || true
4-callback_client 4-callback_server 4-callback_simulator: _4-callback_client.c _4-callback_server.c _4-callback_simulator.c
make -f 4-callback.mk
./5-globals_server 12345 >> $@ 2>&1&
./5-globals_client 127.0.0.1 12345 >> $@ 2>&1
sleep 1
+ echo '$$' >> $@
echo '$$ ./test_simulator platform.xml test.xml' >> $@
./5-globals_simulator gtut-platform.xml 3-args.xml >> $@ 2>&1
echo '$$' >> $@
+ killall 5-globals_server 5-globals_client 2>/dev/null || true
5-globals_client 5-globals_server 5-globals_simulator: _5-globals_client.c _5-globals_server.c _5-globals_simulator.c
make -f 5-globals.mk
if [ -e 5-globals.mk ] ; then make -f 5-globals.mk clean; fi
rm -f _5-globals_client.c _5-globals_server.c _5-globals_simulator.c 5-globals.trace 5-globals.mk
+# Lesson 6: logs
+########################################
+
+6-logs.output: 6-logs_client 6-logs_server 6-logs_simulator 6-logs.output.verbose 6-logs.output.error
+ echo '$$ ./test_server 12345 & ./test_client 127.0.0.1 12345' > $@
+ ./6-logs_server 12345 2>&1 |sed s/6-logs/test/ >> $@ 2>&1&
+ ./6-logs_client 127.0.0.1 12345 2>&1 |sed s/6-logs/test/ >> $@ 2>&1
+ sleep 1
+ echo '$$' >> $@
+ echo '$$ ./test_simulator platform.xml test.xml' >> $@
+ ./6-logs_simulator gtut-platform.xml 3-args.xml 2>&1 |sed s/6-logs/test/ >> $@ 2>&1
+ echo '$$' >> $@
+ killall 6-logs_server 6-logs_client 2>/dev/null || true
+
+6-logs.output.verbose: 6-logs_client 6-logs_server 6-logs_simulator
+ echo '$$ ./test_server 12345 --gras-log=test.thres=verbose & ./test_client 127.0.0.1 12345 --gras-log=test.thres=verbose' > $@
+ ./6-logs_server 12345 --gras-log=test.thres=verbose 2>&1 |sed s/6-logs/test/ >> $@ 2>&1&
+ ./6-logs_client 127.0.0.1 12345 --gras-log=test.thres=verbose 2>&1 |sed s/6-logs/test/ >> $@ 2>&1
+ sleep 1
+ echo '$$' >> $@
+ echo '$$ ./test_simulator platform.xml test.xml --gras-log=test.thres=verbose' >> $@
+ ./6-logs_simulator gtut-platform.xml 3-args.xml --gras-log=test.thres=verbose 2>&1 |sed s/6-logs/test/ >> $@ 2>&1
+ echo '$$' >> $@
+ killall 6-logs_server 6-logs_client 2>/dev/null || true
+
+6-logs.output.error: 6-logs_client 6-logs_server 6-logs_simulator
+ echo '$$ ./test_server 12345 --gras-log=root.thres=error & ./test_client 127.0.0.1 12345 --gras-log=root.thres=error' > $@
+ ./6-logs_server 12345 --gras-log=root.thres=error 2>&1 |sed s/6-logs/test/ >> $@ 2>&1&
+ ./6-logs_client 127.0.0.1 12345 --gras-log=root.thres=error 2>&1 |sed s/6-logs/test/ >> $@ 2>&1
+ sleep 1
+ echo '$$' >> $@
+ echo '$$ ./test_simulator platform.xml test.xml --gras-log=root.thres=error' >> $@
+ ./6-logs_simulator gtut-platform.xml 3-args.xml --gras-log=root.thres=error 2>&1 |sed s/6-logs/test/ >> $@ 2>&1
+ echo '$$' >> $@
+ killall 6-logs_server 6-logs_client 2>/dev/null || true
+
+
+6-logs_client 6-logs_server 6-logs_simulator: _6-logs_client.c _6-logs_server.c _6-logs_simulator.c
+ make -f 6-logs.mk
+
+_6-logs_client.c _6-logs_server.c _6-logs_simulator.c: 6-logs.c 3-args.xml
+ ../../tools/gras/gras_stub_generator 6-logs 3-args.xml >/dev/null
+
+clean::
+ if [ -e 6-logs.mk ] ; then make -f 6-logs.mk clean; fi
+ rm -f _6-logs_client.c _6-logs_server.c _6-logs_simulator.c 6-logs.trace 6-logs.mk
+
explains how to install the framework and setup your own projects. Then,
an example distributed application is builded incrementaly to show the
several aspects of the framework.
+ - \ref GRAS_tut_tour_install
+ - \ref GRAS_tut_tour_setup
+ - \ref GRAS_tut_tour_simpleexchange
+ - \ref GRAS_tut_tour_args
+ - \ref GRAS_tut_tour_callbacks
+ - \ref GRAS_tut_tour_globals
+ - \ref GRAS_tut_tour_logs
\htmlonly <!--
DOXYGEN_NAVBAR_LABEL="Tutorial"
messages, which the client can stop remotely properly. That's already
something, hu?
-\ref GRAS_tut_tour_timer
+\ref GRAS_tut_tour_logs
*/
--- /dev/null
+/**
+@page GRAS_tut_tour_logs Lesson 6: Logging informations properly
+
+\section GRAS_tut_tour_logs_intro Introduction
+
+Let's have another look at the output of the program we came up with in
+lesson 5:
+\include 5-globals.output
+
+It is a bit difficult to read, isn't it? Indeed, it is hard to identify
+which process printed which line. It would be possible to add [server] in
+any messages comming from the server and do the same for every process
+running. Idealy, we would also add the location at which the message was
+generated (using __FILE__ and __LINE__) to help debuging, as well as a
+timestamping so that we can still reorder the messages in RL when they get
+intermixed (yeah, it happen, and there is not much to do against it).
+At the end, each time we would like to print a little "hello" debugging
+message, we would have to write 3 lines of arguments to fprintf, which is
+not that practical.
+
+That is why there is a support for proper logging in GRAS. Technically
+speaking, it is not part of GRAS but of XBT, which is the toolbox on which
+the whole SimGrid library is built, but that's the same for us.
+
+This logging library follows the spirit of another one called log4j, which
+is more or less the reference in the domain. The original version is for
+Java, as the name implies, and there was reimplementation for Python
+(log4py), C/C++ (log4c) and so on. Since one of the credo of the GRAS
+framework is that we don't want any external dependency to ease the
+deployment in grid settings, we reimplemented a version of our own.
+
+One of the strong idea of log4j is that log events get structured to give
+the user a fine control at run time of what gets displayed and what don't.
+For that, <i>log event</i> are produced into <i>log channels</i> at a given
+<i>log priority</i>. Then, you can select the minimal priority an event
+should have on a given channel to get displayed.
+
+Then, to keep things managable even when the number of channels increase,
+the channels form a tree and properties get inherited from parent channel to
+childs. Have a look at the existing channels in SimGrid: \ref XBT_log_cats.
+You see that for example, the <tt>gras</tt> channel have 5 subchannels (at
+time of writing): <tt>gras_ddt</tt>, <tt>gras_msg</tt>, <tt>gras_timer</tt>,
+<tt>gras_trp</tt> and <tt>gras_virtu</tt>. If you open or close the
+<tt>gras</tt> channel, it automatically affects all those subchannels (and
+their respective subchannels too). Finally, channels are not just open or
+closed, but filter messages below a given priority (as we said). The
+priorities are defined by type #e_xbt_log_priority_t.
+
+That is all you really need to know about the logs before diving into
+practice. If you want more information on that topic, refer to the \ref
+XBT_log section, which contains much more information than this page.
+
+\section GRAS_tut_tour_logs_practice Putting logs in practice in a program
+
+Enough with theory, let's change our example so that it uses proper
+loggings. The first thing to do is to add a new channel in the existing
+hierarchy. There is 4 macros to create log channels, depending on the kind
+of channel we want:
+- XBT_LOG_NEW_CATEGORY(MyCat,desc); Create a new root
+- XBT_LOG_NEW_SUBCATEGORY(MyCat, ParentCat,desc); Create a new category being child of the category ParentCat
+- XBT_LOG_NEW_DEFAULT_CATEGORY(MyCat,desc); Like XBT_LOG_NEW_CATEGORY, but the new category is the default one in this file
+- XBT_LOG_NEW_DEFAULT_SUBCATEGORY(MyCat, ParentCat,desc); Like XBT_LOG_NEW_SUBCATEGORY, but the new category is the default one in this file
+
+What we want here is a root category (it does not belong to any existing
+channel, for sure), and we want it to be the default one in our file (of
+course, it's the only one).
+\dontinclude 6-logs.c
+\skip XBT_LOG
+\until XBT_LOG
+
+Then, we change any call to fprintf to one of the logging macros. There is a
+plenty of them, called <priority><nb args>, such as #DEBUG10,
+which produces a debuging log event onto the default category. You have to
+declare the name of arguments as part of the macro name for compatibility
+with old compilers not accepting variable number of arguments. Here is a
+partial list of the existing macros: #DEBUG10, #VERB6, #INFO8, #WARN6,
+#ERROR6 and #CRITICAL6. For each priority, this is the biggest macro (and
+the others are not documented for sake of clarity in the relevant document).
+Ie, VERB10 does not exist, but VERB0 does exist. I may add more if someone
+wants more, but that should be enough for most purposes.
+
+\section GRAS_tut_tour_logs_recap Recapping everything together
+
+Once we changed any fprintf of our code to some of these macros, the program
+may read:
+\include 6-logs.c
+
+And the output now looks better:
+\include 6-logs.output
+
+\section GRAS_tut_tour_logs_config The user side: configuring logs at run time
+
+Once we changed our program to use proper logging, it is naturally possible
+to choose at run time what we want to see. For example, if we want more
+details about our code, we should do (note that a VERBOSE line appears on
+client side):
+\include 6-logs.output.verbose
+
+On the contrary, if we want to reduce the amount of logging, we may want to
+do: \include 6-logs.output.error
+
+Again, you should refer to the \ref XBT_log section for more information on
+how to configure the logs. Or you can proceed with the next lesson, of
+course.
+
+\ref GRAS_tut_tour_timer
+*/
DOXYGEN_NAVBAR_CHILD "3: Process args"=GRAS_tut_tour_args.html
DOXYGEN_NAVBAR_CHILD "4: Callbacks"=GRAS_tut_tour_callbacks.html
DOXYGEN_NAVBAR_CHILD "5: Callbacks"=GRAS_tut_tour_globals.html
+ DOXYGEN_NAVBAR_CHILD "6: Logs"=GRAS_tut_tour_logs.html
--> \endhtmlonly
- \ref GRAS_tut_tour_install
- \ref GRAS_tut_tour_args
- \ref GRAS_tut_tour_callbacks
- \ref GRAS_tut_tour_globals
+ - \ref GRAS_tut_tour_logs
<hr>