From a6975c1d754a1ba5bfb9e23f0b26692c746e6f9c Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Sat, 13 Jan 2018 01:35:33 +0100
Subject: Handled the logs from the GUI, the command line and the Python
 bindings.

---
 ChangeLog                               |  72 +++++++++
 plugins/dex/loading.c                   |   2 +-
 plugins/elf/format.c                    |   2 +-
 plugins/elf/loading.c                   |   2 +-
 plugins/elf/symbols.c                   |   2 +-
 plugins/pychrysa/arch/vmpa.c            |  12 --
 plugins/pychrysa/core/Makefile.am       |   1 +
 plugins/pychrysa/core/formats.c         |   2 +-
 plugins/pychrysa/core/logs.c            | 278 ++++++++++++++++++++++++++++++++
 plugins/pychrysa/core/logs.h            |  42 +++++
 plugins/pychrysa/core/module.c          |   2 +
 plugins/pychrysa/gui/panels/Makefile.am |   1 -
 plugins/pychrysa/gui/panels/log.c       | 200 -----------------------
 plugins/pychrysa/gui/panels/log.h       |  42 -----
 plugins/pychrysa/gui/panels/module.c    |   2 -
 src/analysis/binary.c                   |   3 +-
 src/analysis/db/certs.c                 |   3 +-
 src/analysis/db/client.c                |   2 +-
 src/analysis/db/server.c                |   2 +-
 src/analysis/disass/area.c              |   2 +-
 src/analysis/disass/disassembler.c      |   1 -
 src/analysis/disass/output.c            |   2 +-
 src/analysis/disass/routines.c          |   2 +-
 src/analysis/loading.c                  |   2 +-
 src/analysis/project.c                  |   2 +-
 src/core/Makefile.am                    |   1 +
 src/core/logs.c                         | 188 +++++++++++++++++++++
 src/core/logs.h                         |  60 +++++++
 src/debug/debugger.c                    |   2 +-
 src/debug/gdbrsp/stream.c               |   2 +-
 src/debug/jdwp/debugger.c               |   2 +-
 src/debug/jdwp/tcp.c                    |   2 +-
 src/format/executable.c                 |   2 +-
 src/format/format.c                     |   1 -
 src/gui/core/theme.c                    |   2 +-
 src/gui/dialogs/identity.c              |   2 +-
 src/gui/menus/debug.c                   |   1 -
 src/gui/panels/log.c                    |  91 +----------
 src/gui/panels/log.h                    |  19 +--
 src/main.c                              |  24 ++-
 tests/core/logs.py                      |  34 ++++
 41 files changed, 727 insertions(+), 389 deletions(-)
 create mode 100644 plugins/pychrysa/core/logs.c
 create mode 100644 plugins/pychrysa/core/logs.h
 delete mode 100644 plugins/pychrysa/gui/panels/log.c
 delete mode 100644 plugins/pychrysa/gui/panels/log.h
 create mode 100644 src/core/logs.c
 create mode 100644 src/core/logs.h
 create mode 100644 tests/core/logs.py

diff --git a/ChangeLog b/ChangeLog
index 0d40fbe..2cfb140 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,75 @@
+18-01-13  Cyrille Bagard <nocbos@gmail.com>
+
+	* plugins/dex/loading.c:
+	* plugins/elf/format.c:
+	* plugins/elf/loading.c:
+	* plugins/elf/symbols.c:
+	Update code.
+
+	* plugins/pychrysa/arch/vmpa.c:
+	Remove temporary code.
+
+	* plugins/pychrysa/core/Makefile.am:
+	Add the 'logs.[ch]' files to libpychrysacore_la_SOURCES.
+
+	* plugins/pychrysa/core/formats.c:
+	Update code.
+
+	* plugins/pychrysa/core/logs.c:
+	* plugins/pychrysa/core/logs.h:
+	New entries: provide logs access from Python.
+
+	* plugins/pychrysa/core/module.c:
+	Update code.
+
+	* plugins/pychrysa/gui/panels/Makefile.am:
+	Remove the 'log.[ch]' files from libpychrysaguipanels_la_SOURCES.
+
+	* plugins/pychrysa/gui/panels/log.h
+	* plugins/pychrysa/gui/panels/log.h
+	Delete entries.
+
+	* plugins/pychrysa/gui/panels/module.c:
+	* src/analysis/binary.c:
+	* src/analysis/db/certs.c:
+	* src/analysis/db/client.c:
+	* src/analysis/db/server.c:
+	* src/analysis/disass/area.c:
+	* src/analysis/disass/disassembler.c:
+	* src/analysis/disass/output.c:
+	* src/analysis/disass/routines.c:
+	* src/analysis/loading.c:
+	* src/analysis/project.c:
+	Update code.
+
+	* src/core/Makefile.am:
+	Add the 'logs.[ch]' files to libcore_la_SOURCES.
+
+	* src/core/logs.c:
+	* src/core/logs.h:
+	New entries: handle the logs from the GUI, the command line and the Python bindings.
+
+	* src/debug/debugger.c:
+	* src/debug/gdbrsp/stream.c:
+	* src/debug/jdwp/debugger.c:
+	* src/debug/jdwp/tcp.c:
+	* src/format/executable.c:
+	* src/format/format.c:
+	* src/gui/core/theme.c:
+	* src/gui/dialogs/identity.c:
+	* src/gui/menus/debug.c:
+	Update code.
+
+	* src/gui/panels/log.c:
+	* src/gui/panels/log.h:
+	Update the feature provided by the log panel.
+
+	* src/main.c:
+	Allow to set the log verbosity from command line.
+
+	* tests/core/logs.py:
+	New entry: perform some extra tests when running the test suite.
+
 18-01-09  Cyrille Bagard <nocbos@gmail.com>
 
 	* plugins/pychrysa/analysis/routine.c:
diff --git a/plugins/dex/loading.c b/plugins/dex/loading.c
index c00d0c5..7a1abf2 100644
--- a/plugins/dex/loading.c
+++ b/plugins/dex/loading.c
@@ -25,8 +25,8 @@
 
 
 #include <i18n.h>
+#include <core/logs.h>
 #include <glibext/delayed-int.h>
-#include <gui/panels/log.h>
 
 
 #include "pool.h"
diff --git a/plugins/elf/format.c b/plugins/elf/format.c
index c12460a..a5c8c92 100644
--- a/plugins/elf/format.c
+++ b/plugins/elf/format.c
@@ -31,7 +31,7 @@
 
 
 #include <i18n.h>
-#include <gui/panels/log.h>
+#include <core/logs.h>
 #include <plugins/pglist.h>
 
 
diff --git a/plugins/elf/loading.c b/plugins/elf/loading.c
index 168c9c6..377eb14 100644
--- a/plugins/elf/loading.c
+++ b/plugins/elf/loading.c
@@ -25,8 +25,8 @@
 
 
 #include <i18n.h>
+#include <core/logs.h>
 #include <glibext/delayed-int.h>
-#include <gui/panels/log.h>
 
 
 #include "elf-int.h"
diff --git a/plugins/elf/symbols.c b/plugins/elf/symbols.c
index b5dc2b8..7bf68f5 100644
--- a/plugins/elf/symbols.c
+++ b/plugins/elf/symbols.c
@@ -33,9 +33,9 @@
 #include <arch/raw.h>
 #include <common/extstr.h>
 #include <core/global.h>
+#include <core/logs.h>
 #include <core/params.h>
 #include <format/mangling/demangler.h>
-#include <gui/panels/log.h>
 
 
 #include "dynamic.h"
diff --git a/plugins/pychrysa/arch/vmpa.c b/plugins/pychrysa/arch/vmpa.c
index aaaede8..413d67b 100644
--- a/plugins/pychrysa/arch/vmpa.c
+++ b/plugins/pychrysa/arch/vmpa.c
@@ -521,18 +521,6 @@ static PyObject *py_vmpa_nb_add(PyObject *o1, PyObject *o2)
 
 
 
-void log_simple_message(/*LogMessageType*/ int type, const char *msg)
-{
-
-}
-
-
-void log_variadic_message(/*LogMessageType*/ int type, const char *fmt, ...)
-{
-
-
-}
-
 
 void change_editor_items_current_view_content(void/*GtkDisplayPanel*/ *view)
 {
diff --git a/plugins/pychrysa/core/Makefile.am b/plugins/pychrysa/core/Makefile.am
index 129b5af..71abfa4 100644
--- a/plugins/pychrysa/core/Makefile.am
+++ b/plugins/pychrysa/core/Makefile.am
@@ -3,6 +3,7 @@ noinst_LTLIBRARIES = libpychrysacore.la
 
 libpychrysacore_la_SOURCES =			\
 	formats.h formats.c					\
+	logs.h logs.c						\
 	module.h module.c					\
 	params.h params.c
 
diff --git a/plugins/pychrysa/core/formats.c b/plugins/pychrysa/core/formats.c
index 8d6bd4f..621277a 100644
--- a/plugins/pychrysa/core/formats.c
+++ b/plugins/pychrysa/core/formats.c
@@ -117,7 +117,7 @@ PyTypeObject *get_python_formats_type(void)
 
         .tp_doc = "Python object for parameters",
 
-        .tp_methods =  py_formats_methods
+        .tp_methods = py_formats_methods
 
     };
 
diff --git a/plugins/pychrysa/core/logs.c b/plugins/pychrysa/core/logs.c
new file mode 100644
index 0000000..8a922c1
--- /dev/null
+++ b/plugins/pychrysa/core/logs.c
@@ -0,0 +1,278 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * logs.c - équivalent Python du fichier "gui/panels/logs.c"
+ *
+ * Copyright (C) 2017 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  Chrysalide is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include "logs.h"
+
+
+#include <pygobject.h>
+
+
+#include <core/logs.h>
+
+
+#include "../helpers.h"
+
+
+
+/* Fournit la verbosité des messages système. */
+static PyObject *py_logs_get_verbosity(PyObject *, PyObject *);
+
+/* Définit la verbosité des messages système. */
+static PyObject *py_logs_set_verbosity(PyObject *, PyObject *);
+
+/* Affiche un message dans le journal des messages système. */
+static PyObject *py_logs_log_message(PyObject *, PyObject *);
+
+/* Définit les constantes pour les types de message. */
+static bool define_python_log_constants(PyTypeObject *);
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : self = classe assurant le lien avec l'éditeur de messages.   *
+*                args = arguments fournis à l'appel.                          *
+*                                                                             *
+*  Description : Fournit la verbosité des messages système.                   *
+*                                                                             *
+*  Retour      : Plus faible niveau des types de message affichés.            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_logs_get_verbosity(PyObject *self, PyObject *args)
+{
+    PyObject *result;                       /* Conversion à retourner      */
+    LogMessageType verbosity;               /* Niveau de filtre de message */
+
+    verbosity = get_log_verbosity();
+
+    result = PyLong_FromUnsignedLong(verbosity);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : self = classe assurant le lien avec l'éditeur de messages.   *
+*                args = arguments fournis à l'appel.                          *
+*                                                                             *
+*  Description : Définit la verbosité des messages système.                   *
+*                                                                             *
+*  Retour      : Rien en équivalent Python.                                   *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_logs_set_verbosity(PyObject *self, PyObject *args)
+{
+    PyObject *result;                       /* Bilan à retourner           */
+    unsigned long verbosity;                /* Niveau de filtre de message */
+
+    if (!PyArg_ParseTuple(args, "k", &verbosity))
+        return NULL;
+
+    set_log_verbosity(verbosity);
+
+    result = Py_None;
+    Py_INCREF(result);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : self = classe assurant le lien avec l'éditeur de messages.   *
+*                args = arguments fournis à l'appel.                          *
+*                                                                             *
+*  Description : Affiche un message dans le journal des messages système.     *
+*                                                                             *
+*  Retour      : Rien en équivalent Python.                                   *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_logs_log_message(PyObject *self, PyObject *args)
+{
+    PyObject *result;                       /* Bilan à retourner           */
+    unsigned long type;                     /* Espèce du message           */
+    const char *msg;                        /* Contenu du message          */
+
+    if (!PyArg_ParseTuple(args, "ks", &type, &msg))
+        return NULL;
+
+    switch (type)
+    {
+        case LMT_INFO:
+        case LMT_PROCESS:
+        case LMT_WARNING:
+        case LMT_ERROR:
+        case LMT_BAD_BINARY:
+            log_simple_message(type, msg);
+            result = Py_None;
+            Py_INCREF(result);
+            break;
+
+        default:
+            PyErr_SetString(PyExc_ValueError,
+                            _("Invalid type of message"));
+            result = NULL;
+            break;
+
+    }
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Fournit un accès à une définition de type à diffuser.        *
+*                                                                             *
+*  Retour      : Définition d'objet pour Python.                              *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+PyTypeObject *get_python_logs_type(void)
+{
+    static PyMethodDef py_logs_methods[] = {
+        {
+            "get_verbosity", (PyCFunction)py_logs_get_verbosity,
+            METH_NOARGS | METH_STATIC,
+            "get_verbosity(, /)\n--\n\nGet the log verbosity."
+        },
+        {
+            "set_verbosity", (PyCFunction)py_logs_set_verbosity,
+            METH_VARARGS | METH_STATIC,
+            "set_verbosity(, /)\n--\n\nSet the log verbosity."
+        },
+        {
+            "log_message", (PyCFunction)py_logs_log_message,
+            METH_VARARGS | METH_STATIC,
+            "log_message(type, msg, /)\n--\n\nDisplay a message in the log window, if any."
+        },
+        { NULL }
+
+    };
+
+    static PyGetSetDef py_logs_getseters[] = {
+        { NULL }
+    };
+
+    static PyTypeObject py_logs_type = {
+
+        PyVarObject_HEAD_INIT(NULL, 0)
+
+        .tp_name = "pychrysalide.core.logs",
+        .tp_basicsize = sizeof(PyObject) + 80,
+
+        .tp_flags = Py_TPFLAGS_DEFAULT,
+
+        .tp_doc = "Python object for logs",
+
+        .tp_methods = py_logs_methods,
+        .tp_getset  = py_logs_getseters
+
+    };
+
+    return &py_logs_type;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : obj_type = type dont le dictionnaire est à compléter.        *
+*                                                                             *
+*  Description : Définit les constantes pour les types de message.            *
+*                                                                             *
+*  Retour      : true en cas de succès de l'opération, false sinon.           *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool define_python_log_constants(PyTypeObject *obj_type)
+{
+    bool result;                            /* Bilan à retourner           */
+
+    result = true;
+
+    result &= PyDict_AddIntMacro(obj_type, LMT_INFO);
+    result &= PyDict_AddIntMacro(obj_type, LMT_PROCESS);
+    result &= PyDict_AddIntMacro(obj_type, LMT_WARNING);
+    result &= PyDict_AddIntMacro(obj_type, LMT_ERROR);
+    result &= PyDict_AddIntMacro(obj_type, LMT_BAD_BINARY);
+    result &= PyDict_AddIntMacro(obj_type, LMT_COUNT);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : module = module dont la définition est à compléter.          *
+*                                                                             *
+*  Description : Prend en charge l'objet 'pychrysalide.gui.panels.LogPanel'.  *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool register_python_logs(PyObject *module)
+{
+    PyTypeObject *py_logs_type;             /* Type Python pour 'logs'     */
+    int ret;                                /* Bilan d'un appel            */
+
+    py_logs_type = get_python_logs_type();
+
+    py_logs_type->tp_new = PyType_GenericNew;
+
+    if (PyType_Ready(py_logs_type) != 0)
+        return false;
+
+    if (!define_python_log_constants(py_logs_type))
+        return false;
+
+    Py_INCREF(py_logs_type);
+    ret = PyModule_AddObject(module, "logs", (PyObject *)py_logs_type);
+
+    return (ret == 0);
+
+}
diff --git a/plugins/pychrysa/core/logs.h b/plugins/pychrysa/core/logs.h
new file mode 100644
index 0000000..f1c7faf
--- /dev/null
+++ b/plugins/pychrysa/core/logs.h
@@ -0,0 +1,42 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * logs.h - prototypes pour l'équivalent Python du fichier "core/logs.h"
+ *
+ * Copyright (C) 2017 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  Chrysalide is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#ifndef _PLUGINS_PYCHRYSA_CORE_LOGS_H
+#define _PLUGINS_PYCHRYSA_CORE_LOGS_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+
+/* Fournit un accès à une définition de type à diffuser. */
+PyTypeObject *get_python_logs_type(void);
+
+/* Prend en charge l'objet 'pychrysalide.core.logs'. */
+bool register_python_logs(PyObject *);
+
+
+
+#endif  /* _PLUGINS_PYCHRYSA_CORE_LOGS_H */
diff --git a/plugins/pychrysa/core/module.c b/plugins/pychrysa/core/module.c
index 6c44197..ff7f828 100644
--- a/plugins/pychrysa/core/module.c
+++ b/plugins/pychrysa/core/module.c
@@ -29,6 +29,7 @@
 
 
 #include "formats.h"
+#include "logs.h"
 #include "params.h"
 #include "../access.h"
 
@@ -81,6 +82,7 @@ bool add_core_module_to_python_module(PyObject *super)
     result = true;
 
     result &= register_python_formats(module);
+    result &= register_python_logs(module);
     result &= register_python_params(module);
 
     if (result)
diff --git a/plugins/pychrysa/gui/panels/Makefile.am b/plugins/pychrysa/gui/panels/Makefile.am
index 12e79ab..99e4c3f 100644
--- a/plugins/pychrysa/gui/panels/Makefile.am
+++ b/plugins/pychrysa/gui/panels/Makefile.am
@@ -2,7 +2,6 @@
 noinst_LTLIBRARIES = libpychrysaguipanels.la
 
 libpychrysaguipanels_la_SOURCES =		\
-	log.h log.c							\
 	module.h module.c					\
 	panel.h panel.c
 
diff --git a/plugins/pychrysa/gui/panels/log.c b/plugins/pychrysa/gui/panels/log.c
deleted file mode 100644
index 686749f..0000000
--- a/plugins/pychrysa/gui/panels/log.c
+++ /dev/null
@@ -1,200 +0,0 @@
-
-/* Chrysalide - Outil d'analyse de fichiers binaires
- * log.c - équivalent Python du fichier "gui/panels/log.c"
- *
- * Copyright (C) 2013-2017 Cyrille Bagard
- *
- *  This file is part of Chrysalide.
- *
- *  Chrysalide is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  Chrysalide is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-
-#include "log.h"
-
-
-#include <pygobject.h>
-
-
-#include <gui/panels/log.h>
-
-
-#include "panel.h"
-#include "../../helpers.h"
-
-
-
-/* Affiche un message dans le journal des messages système. */
-static PyObject *py_log_panel_log_message(PyObject *, PyObject *);
-
-/* Définit les constantes pour les types de message. */
-static bool define_python_log_constants(PyTypeObject *);
-
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : self = classe assurant le lien avec l'éditeur de messages.   *
-*                args = arguments fournis à l'appel.                          *
-*                                                                             *
-*  Description : Affiche un message dans le journal des messages système.     *
-*                                                                             *
-*  Retour      : Rien en équivalent Python.                                   *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static PyObject *py_log_panel_log_message(PyObject *self, PyObject *args)
-{
-    PyObject *result;                       /* Bilan à retourner           */
-    LogMessageType type;                    /* Espèce du message           */
-    const char *msg;                        /* Contenu du message          */
-
-    if (!PyArg_ParseTuple(args, "ls", &type, &msg))
-        return NULL;
-
-    switch (type)
-    {
-        case LMT_INFO:
-        case LMT_BAD_BINARY:
-        case LMT_PROCESS:
-        case LMT_ERROR:
-        case LMT_WARNING:
-            log_simple_message(type, msg);
-            result = Py_None;
-            Py_INCREF(result);
-            break;
-
-        default:
-            PyErr_SetString(PyExc_ValueError, 
-                            _("Invalid type of message"));
-            result = NULL;
-            break;
-
-    }
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : obj_type = type dont le dictionnaire est à compléter.        *
-*                                                                             *
-*  Description : Définit les constantes pour les types de message.            *
-*                                                                             *
-*  Retour      : true en cas de succès de l'opération, false sinon.           *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static bool define_python_log_constants(PyTypeObject *obj_type)
-{
-    bool result;                            /* Bilan à retourner           */
-
-    result = true;
-
-    result &= PyDict_AddIntMacro(obj_type, LMT_INFO);
-    result &= PyDict_AddIntMacro(obj_type, LMT_BAD_BINARY);
-    result &= PyDict_AddIntMacro(obj_type, LMT_PROCESS);
-    result &= PyDict_AddIntMacro(obj_type, LMT_ERROR);
-    result &= PyDict_AddIntMacro(obj_type, LMT_WARNING);
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : -                                                            *
-*                                                                             *
-*  Description : Fournit un accès à une définition de type à diffuser.        *
-*                                                                             *
-*  Retour      : Définition d'objet pour Python.                              *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-PyTypeObject *get_python_log_panel_type(void)
-{
-    static PyMethodDef py_log_panel_methods[] = {
-        {
-            "log_message", (PyCFunction)py_log_panel_log_message,
-            METH_VARARGS | METH_STATIC,
-            "log_message(type, msg, /)\n--\n\nDisplay a message in the log window, if any."
-        },
-        { NULL }
-    };
-
-    static PyGetSetDef py_log_panel_getseters[] = {
-        { NULL }
-    };
-
-    static PyTypeObject py_log_panel_type = {
-
-        PyVarObject_HEAD_INIT(NULL, 0)
-
-        .tp_name        = "pychrysalide.gui.panels.LogPanel",
-        .tp_basicsize   = sizeof(PyGObject),
-
-        .tp_flags       = Py_TPFLAGS_DEFAULT,
-
-        .tp_doc         = "PyChrysalide log panel",
-
-        .tp_methods     = py_log_panel_methods,
-        .tp_getset      = py_log_panel_getseters
-
-    };
-
-    return &py_log_panel_type;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : module = module dont la définition est à compléter.          *
-*                                                                             *
-*  Description : Prend en charge l'objet 'pychrysalide.gui.panels.LogPanel'.  *
-*                                                                             *
-*  Retour      : Bilan de l'opération.                                        *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-bool register_python_log_panel(PyObject *module)
-{
-    PyTypeObject *py_log_panel_type;        /* Type Python 'LoadedBinary'  */
-    PyObject *dict;                         /* Dictionnaire du module      */
-
-    py_log_panel_type = get_python_log_panel_type();
-
-    dict = PyModule_GetDict(module);
-
-    if (!register_class_for_pygobject(dict, G_TYPE_LOG_PANEL, py_log_panel_type, get_python_panel_item_type()))
-        return false;
-
-    if (!define_python_log_constants(py_log_panel_type))
-        return false;
-
-    return true;
-
-}
diff --git a/plugins/pychrysa/gui/panels/log.h b/plugins/pychrysa/gui/panels/log.h
deleted file mode 100644
index 49da96c..0000000
--- a/plugins/pychrysa/gui/panels/log.h
+++ /dev/null
@@ -1,42 +0,0 @@
-
-/* Chrysalide - Outil d'analyse de fichiers binaires
- * log.h - prototypes pour l'équivalent Python du fichier "gui/panels/log.h"
- *
- * Copyright (C) 2013-2017 Cyrille Bagard
- *
- *  This file is part of Chrysalide.
- *
- *  Chrysalide is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  Chrysalide is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-
-#ifndef _PLUGINS_PYCHRYSA_GUI_PANELS_LOG_H
-#define _PLUGINS_PYCHRYSA_GUI_PANELS_LOG_H
-
-
-#include <Python.h>
-#include <stdbool.h>
-
-
-
-/* Fournit un accès à une définition de type à diffuser. */
-PyTypeObject *get_python_log_panel_type(void);
-
-/* Prend en charge l'objet 'pychrysalide.gui.panels.LogPanel'. */
-bool register_python_log_panel(PyObject *);
-
-
-
-#endif  /* _PLUGINS_PYCHRYSA_GUI_PANELS_LOG_H */
diff --git a/plugins/pychrysa/gui/panels/module.c b/plugins/pychrysa/gui/panels/module.c
index d5040e3..21b487e 100644
--- a/plugins/pychrysa/gui/panels/module.c
+++ b/plugins/pychrysa/gui/panels/module.c
@@ -28,7 +28,6 @@
 #include <assert.h>
 
 
-#include "log.h"
 #include "panel.h"
 #include "../../access.h"
 
@@ -81,7 +80,6 @@ bool add_gui_panels_module_to_python_module(PyObject *super)
     result = true;
 
     result &= register_python_panel_item(module);
-    result &= register_python_log_panel(module);
 
     if (result)
         register_access_to_python_module("pychrysalide.gui.panels", module);
diff --git a/src/analysis/binary.c b/src/analysis/binary.c
index 5b2caf0..2769291 100644
--- a/src/analysis/binary.c
+++ b/src/analysis/binary.c
@@ -46,14 +46,15 @@
 #include "../core/collections.h"
 #include "../core/formats.h"
 #include "../core/global.h"
+#include "../core/logs.h"
 #include "../core/params.h"
 #include "../core/processors.h"
 //#include "../glibext/chrysamarshal.h"
+#include "../glibext/gloadedpanel.h"
 #include "../gtkext/easygtk.h"
 #include "../gtkext/gtkblockdisplay.h"
 #include "../gtkext/gtkdisplaypanel.h"
 #include "../gtkext/gtkgraphdisplay.h"
-#include "../gui/panels/log.h"
 
 
 
diff --git a/src/analysis/db/certs.c b/src/analysis/db/certs.c
index c6b49a8..083ef7d 100644
--- a/src/analysis/db/certs.c
+++ b/src/analysis/db/certs.c
@@ -24,6 +24,7 @@
 #include "certs.h"
 
 
+#include <glib.h>
 #include <malloc.h>
 #include <stdio.h>
 #include <openssl/err.h>
@@ -37,7 +38,7 @@
 #include <i18n.h>
 
 
-#include "../../gui/panels/log.h"
+#include "../../core/logs.h"
 
 
 
diff --git a/src/analysis/db/client.c b/src/analysis/db/client.c
index 769eab7..aff235c 100644
--- a/src/analysis/db/client.c
+++ b/src/analysis/db/client.c
@@ -41,7 +41,7 @@
 #include "misc/rlestr.h"
 #include "../../common/io.h"
 #include "../../common/xdg.h"
-#include "../../gui/panels/log.h"
+#include "../../core/logs.h"
 
 
 
diff --git a/src/analysis/db/server.c b/src/analysis/db/server.c
index 6155b6d..219b8b6 100644
--- a/src/analysis/db/server.c
+++ b/src/analysis/db/server.c
@@ -41,8 +41,8 @@
 #include "misc/rlestr.h"
 #include "../../common/io.h"
 #include "../../common/xdg.h"
+#include "../../core/logs.h"
 #include "../../core/params.h"
-#include "../../gui/panels/log.h"
 
 
 
diff --git a/src/analysis/disass/area.c b/src/analysis/disass/area.c
index f97a5c9..f7acb72 100644
--- a/src/analysis/disass/area.c
+++ b/src/analysis/disass/area.c
@@ -38,9 +38,9 @@
 #include "../../common/bits.h"
 #include "../../common/sort.h"
 #include "../../core/global.h"
+#include "../../core/logs.h"
 #include "../../format/format.h"
 #include "../../glibext/delayed-int.h"
-#include "../../gui/panels/log.h"
 
 
 
diff --git a/src/analysis/disass/disassembler.c b/src/analysis/disass/disassembler.c
index 7a066fc..bb69c0e 100644
--- a/src/analysis/disass/disassembler.c
+++ b/src/analysis/disass/disassembler.c
@@ -41,7 +41,6 @@
 #include "../../format/format.h"
 #include "../../glibext/delayed-int.h"
 #include "../../glibext/generators/prologue.h"
-#include "../../gui/panels/log.h"
 #include "../../plugins/pglist.h"
 
 
diff --git a/src/analysis/disass/output.c b/src/analysis/disass/output.c
index f9656cf..3cc282a 100644
--- a/src/analysis/disass/output.c
+++ b/src/analysis/disass/output.c
@@ -30,9 +30,9 @@
 #include <i18n.h>
 
 
+#include "../../core/logs.h"
 #include "../../format/format.h"
 #include "../../glibext/generators/rborder.h"
-#include "../../gui/panels/log.h"
 
 
 
diff --git a/src/analysis/disass/routines.c b/src/analysis/disass/routines.c
index 63a32cf..bc4247c 100644
--- a/src/analysis/disass/routines.c
+++ b/src/analysis/disass/routines.c
@@ -28,8 +28,8 @@
 #include "limit.h"
 #include "loop.h"
 #include "rank.h"
+#include "../../core/logs.h"
 #include "../../glibext/delayed-int.h"
-#include "../../gui/panels/log.h"
 
 
 
diff --git a/src/analysis/loading.c b/src/analysis/loading.c
index f8dc2c3..38d130e 100644
--- a/src/analysis/loading.c
+++ b/src/analysis/loading.c
@@ -26,9 +26,9 @@
 
 #include "../core/formats.h"
 #include "../core/global.h"
+#include "../core/logs.h"
 #include "../glibext/delayed-int.h"
 #include "../glibext/signal.h"
-#include "../gui/panels/log.h"
 
 
 
diff --git a/src/analysis/project.c b/src/analysis/project.c
index 31376de..a600788 100644
--- a/src/analysis/project.c
+++ b/src/analysis/project.c
@@ -37,10 +37,10 @@
 #include "loading.h"
 #include "../common/xml.h"
 #include "../core/global.h"
+#include "../core/logs.h"
 #include "../core/params.h"
 #include "../glibext/delayed-int.h"
 #include "../gui/core/panels.h"
-#include "../gui/panels/log.h"
 #include "../gui/panels/panel.h"
 #include "../format/format.h"
 
diff --git a/src/core/Makefile.am b/src/core/Makefile.am
index 26d43a5..c7700a6 100755
--- a/src/core/Makefile.am
+++ b/src/core/Makefile.am
@@ -6,6 +6,7 @@ libcore_la_SOURCES =					\
 	core.h core.c						\
 	formats.h formats.c					\
 	global.h global.c					\
+	logs.h logs.c						\
 	params.h params.c					\
 	processors.h processors.c
 
diff --git a/src/core/logs.c b/src/core/logs.c
new file mode 100644
index 0000000..f92e581
--- /dev/null
+++ b/src/core/logs.c
@@ -0,0 +1,188 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * logs.c - diffusion de messages d'alerte ou informatifs
+ *
+ * Copyright (C) 2017 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  Chrysalide is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "logs.h"
+
+
+#include "../gui/core/panels.h"
+#include "../gui/panels/log.h"
+
+
+
+/* Conserve le niveau de filtre des messages */
+static LogMessageType _verbosity = LMT_COUNT;
+
+
+/* Affiche un message dans le terminal courant. */
+static void print_message_without_gui(LogMessageType, const char *);
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Fournit la verbosité des messages système.                   *
+*                                                                             *
+*  Retour      : Plus faible niveau des types de message affichés.            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+LogMessageType get_log_verbosity(void)
+{
+    return _verbosity;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : level = plus faible niveau des types de message affichés.    *
+*                                                                             *
+*  Description : Définit la verbosité des messages système.                   *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void set_log_verbosity(LogMessageType level)
+{
+    _verbosity = level;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : type = espèce du message à ajouter.                          *
+*                msg  = message à faire apparaître à l'écran.                 *
+*                                                                             *
+*  Description : Affiche un message dans le journal des messages système.     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void log_simple_message(LogMessageType type, const char *msg)
+{
+    GPanelItem *item;                       /* Eventuel affichage présent  */
+
+    if (type >= _verbosity)
+    {
+        item = get_panel_item_by_name(PANEL_LOG_ID);
+
+        if (item != NULL)
+            g_log_panel_add_message(G_LOG_PANEL(item), type, msg);
+
+        else
+            print_message_without_gui(type, msg);
+
+    }
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : type = espèce du message à ajouter.                          *
+*                fmt  = format du message à faire apparaître à l'écran.       *
+*                ...  = éventuels arguments venant compléter le message.      *
+*                                                                             *
+*  Description : Affiche un message dans le journal des messages système.     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void log_variadic_message(LogMessageType type, const char *fmt, ...)
+{
+    size_t len;                             /* Taille tampon disponible    */
+    char *buffer;                           /* Tampon du msg reconstitué   */
+    int ret;                                /* Bilan d'une impression      */
+    char *ptr;                              /* Nouvelle allocation         */
+    va_list ap;                             /* Liste d'arguments variable  */
+
+    len = VARIADIC_LOG_BUFSIZE;
+    buffer = calloc(len, sizeof(char));
+
+    while (buffer != NULL)
+    {
+        va_start(ap, fmt);
+        ret = vsnprintf(buffer, len, fmt, ap);
+        va_end(ap);
+
+        if (ret >= 0 && ret < len) break;
+
+        else
+        {
+            if (ret > -1) len += 1;     /* glibc 2.1 */
+            else len *= 2;              /* glibc 2.0 */
+
+            if ((ptr = realloc(buffer, len)) == NULL)
+            {
+                free(buffer);
+                buffer = NULL;
+            }
+            else buffer = ptr;
+
+        }
+
+    }
+
+    if (buffer != NULL)
+    {
+        log_simple_message(type, buffer);
+
+        free(buffer);
+
+    }
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : type = espèce du message à ajouter.                          *
+*                msg  = message à faire apparaître à l'écran.                 *
+*                                                                             *
+*  Description : Affiche un message dans le terminal courant.                 *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void print_message_without_gui(LogMessageType type, const char *msg)
+{
+    printf("!! MSG :: %s\n", msg);
+
+}
diff --git a/src/core/logs.h b/src/core/logs.h
new file mode 100644
index 0000000..2199cc1
--- /dev/null
+++ b/src/core/logs.h
@@ -0,0 +1,60 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * logs.h - prototypes pour la diffusion de messages d'alerte ou informatifs
+ *
+ * Copyright (C) 2017 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  Chrysalide is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _CORE_LOGS_H
+#define _CORE_LOGS_H
+
+
+#include <i18n.h>
+
+
+
+/* Type de messages disponibles */
+typedef enum _LogMessageType
+{
+    LMT_INFO,                               /* Information sur l'exécution */
+    LMT_PROCESS,                            /* Début de tâche quelconque   */
+    LMT_WARNING,                            /* Avertissment à remonter     */
+    LMT_ERROR,                              /* Erreur de traitement        */
+    LMT_BAD_BINARY,                         /* Binaire malformé            */
+
+    LMT_COUNT
+
+} LogMessageType;
+
+
+/* Fournit la verbosité des messages système. */
+LogMessageType get_log_verbosity(void);
+
+/* Définit la verbosité des messages système. */
+void set_log_verbosity(LogMessageType);
+
+/* Affiche un message dans le journal des messages système. */
+void log_simple_message(LogMessageType, const char *);
+
+/* Affiche un message dans le journal des messages système. */
+void log_variadic_message(LogMessageType, const char *, ...);
+
+
+
+#endif  /* _CORE_LOGS_H */
diff --git a/src/debug/debugger.c b/src/debug/debugger.c
index 85ca241..4635d0e 100644
--- a/src/debug/debugger.c
+++ b/src/debug/debugger.c
@@ -35,8 +35,8 @@
 
 #include "debugger-int.h"
 #include "../common/sort.h"
+#include "../core/logs.h"
 #include "../glibext/chrysamarshal.h"
-#include "../gui/panels/log.h"
 #include "../plugins/pglist.h"
 
 
diff --git a/src/debug/gdbrsp/stream.c b/src/debug/gdbrsp/stream.c
index 979ed9b..d75cff4 100644
--- a/src/debug/gdbrsp/stream.c
+++ b/src/debug/gdbrsp/stream.c
@@ -36,7 +36,7 @@
 #include "stream-int.h"
 #include "utils.h"
 #include "../../common/dllist.h"
-#include "../../gui/panels/log.h"
+#include "../../core/logs.h"
 
 
 
diff --git a/src/debug/jdwp/debugger.c b/src/debug/jdwp/debugger.c
index efe00d0..b73c8a3 100644
--- a/src/debug/jdwp/debugger.c
+++ b/src/debug/jdwp/debugger.c
@@ -35,7 +35,7 @@
 #include "tcp.h"
 #include "../debugger-int.h"
 #include "../stream.h"
-#include "../../gui/panels/log.h"
+#include "../../core/logs.h"
 
 
 
diff --git a/src/debug/jdwp/tcp.c b/src/debug/jdwp/tcp.c
index 92dae0a..5059419 100644
--- a/src/debug/jdwp/tcp.c
+++ b/src/debug/jdwp/tcp.c
@@ -40,7 +40,7 @@
 #include "sets/list.h"
 #include "../stream-int.h"
 #include "../../common/net.h"
-#include "../../gui/panels/log.h"
+#include "../../core/logs.h"
 
 
 
diff --git a/src/format/executable.c b/src/format/executable.c
index 6afe8b5..1f46721 100644
--- a/src/format/executable.c
+++ b/src/format/executable.c
@@ -32,7 +32,7 @@
 
 #include "executable-int.h"
 #include "format.h"
-#include "../gui/panels/log.h"
+#include "../core/logs.h"
 
 
 
diff --git a/src/format/format.c b/src/format/format.c
index ec8e5fb..1ab7efa 100644
--- a/src/format/format.c
+++ b/src/format/format.c
@@ -34,7 +34,6 @@
 #include "preload.h"
 #include "../arch/processor.h"
 #include "../common/sort.h"
-#include "../gui/panels/log.h"
 #include "../plugins/pglist.h"
 
 
diff --git a/src/gui/core/theme.c b/src/gui/core/theme.c
index 895a1a5..9c3c63b 100644
--- a/src/gui/core/theme.c
+++ b/src/gui/core/theme.c
@@ -38,9 +38,9 @@
 #include <i18n.h>
 
 
-#include "../panels/log.h"
 #include "../../common/extstr.h"
 #include "../../common/xdg.h"
+#include "../../core/logs.h"
 #include "../../core/params.h"
 
 
diff --git a/src/gui/dialogs/identity.c b/src/gui/dialogs/identity.c
index 0f6a111..3df2e91 100644
--- a/src/gui/dialogs/identity.c
+++ b/src/gui/dialogs/identity.c
@@ -30,8 +30,8 @@
 #include <i18n.h>
 
 
-#include "../panels/log.h"
 #include "../../analysis/db/keymgn.h"
+#include "../../core/logs.h"
 
 
 
diff --git a/src/gui/menus/debug.c b/src/gui/menus/debug.c
index cb270ff..3e785b5 100644
--- a/src/gui/menus/debug.c
+++ b/src/gui/menus/debug.c
@@ -32,7 +32,6 @@
 
 #include "../../debug/debugger.h"   /* REMME ! */
 #include "../../gtkext/easygtk.h"
-#include "../../gui/panels/log.h"
 
 
 
diff --git a/src/gui/panels/log.c b/src/gui/panels/log.c
index 2fd8f4f..e547a03 100644
--- a/src/gui/panels/log.c
+++ b/src/gui/panels/log.c
@@ -88,9 +88,6 @@ static void g_log_panel_dispose(GLogPanel *);
 static void g_log_panel_finalize(GLogPanel *);
 
 /* Affiche un message dans le journal des messages système. */
-static void _log_simple_message(LogMessageType, char *);
-
-/* Affiche un message dans le journal des messages système. */
 static gboolean log_message(log_data *);
 
 
@@ -270,28 +267,9 @@ GPanelItem *g_log_panel_new(void)
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : type = espèce du message à ajouter.                          *
-*                msg  = message à faire apparaître à l'écran.                 *
-*                                                                             *
-*  Description : Affiche un message dans le journal des messages système.     *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-void log_simple_message(LogMessageType type, const char *msg)
-{
-    _log_simple_message(type, strdup(msg));
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : type = espèce du message à ajouter.                          *
-*                msg  = message à faire apparaître à l'écran.                 *
+*  Paramètres  : panel = instance d'objet GLib à traiter.                     *
+*                type  = espèce du message à ajouter.                         *
+*                msg   = message à faire apparaître à l'écran.                *
 *                                                                             *
 *  Description : Affiche un message dans le journal des messages système.     *
 *                                                                             *
@@ -301,18 +279,15 @@ void log_simple_message(LogMessageType type, const char *msg)
 *                                                                             *
 ******************************************************************************/
 
-static void _log_simple_message(LogMessageType type, char *msg)
+void g_log_panel_add_message(GLogPanel *panel, LogMessageType type, const char *msg)
 {
-    GPanelItem *item;                       /* Intermédiaire mis en place  */
     log_data *data;                         /* Paramètres à joindre        */
 
-    item = get_panel_item_by_name(PANEL_LOG_ID);
-
     data = (log_data *)calloc(1, sizeof(log_data));
 
-    data->item = item;
+    data->item = G_PANEL_ITEM(panel);
     data->type = type;
-    data->msg = msg;
+    data->msg = strdup(msg);
 
     g_object_ref(G_OBJECT(data->item));
 
@@ -323,60 +298,6 @@ static void _log_simple_message(LogMessageType type, char *msg)
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : type = espèce du message à ajouter.                          *
-*                fmt  = format du message à faire apparaître à l'écran.       *
-*                ...  = éventuels arguments venant compléter le message.      *
-*                                                                             *
-*  Description : Affiche un message dans le journal des messages système.     *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-void log_variadic_message(LogMessageType type, const char *fmt, ...)
-{
-    size_t len;                             /* Taille tampon disponible    */
-    char *buffer;                           /* Tampon du msg reconstitué   */
-    int ret;                                /* Bilan d'une impression      */
-    char *ptr;                              /* Nouvelle allocation         */
-    va_list ap;                             /* Liste d'arguments variable  */
-
-    len = VARIADIC_LOG_BUFSIZE;
-    buffer = calloc(len, sizeof(char));
-
-    while (buffer != NULL)
-    {
-        va_start(ap, fmt);
-        ret = vsnprintf(buffer, len, fmt, ap);
-        va_end(ap);
-
-        if (ret >= 0 && ret < len) break;
-
-        else
-        {
-            if (ret > -1) len += 1;     /* glibc 2.1 */
-            else len *= 2;              /* glibc 2.0 */
-
-            if ((ptr = realloc(buffer, len)) == NULL)
-            {
-                free(buffer);
-                buffer = NULL;
-            }
-            else buffer = ptr;
-
-        }
-
-    }
-
-    _log_simple_message(type, buffer);
-
-}
-
-
-/******************************************************************************
-*                                                                             *
 *  Paramètres  : data = paramètres destinés à l'affichage d'un message.       *
 *                                                                             *
 *  Description : Affiche un message dans le journal des messages système.     *
diff --git a/src/gui/panels/log.h b/src/gui/panels/log.h
index e37348a..dab8581 100644
--- a/src/gui/panels/log.h
+++ b/src/gui/panels/log.h
@@ -30,6 +30,7 @@
 
 
 #include "panel.h"
+#include "../../core/logs.h"
 
 
 
@@ -55,19 +56,6 @@ typedef struct _GLogPanel GLogPanel;
 typedef struct _GLogPanelClass GLogPanelClass;
 
 
-/* Type de messages disponibles */
-typedef enum _LogMessageType
-{
-    LMT_INFO,                               /* Information sur l'exécution */
-    LMT_BAD_BINARY,                         /* Binaire malformé            */
-    LMT_PROCESS,                            /* Début de tâche quelconque   */
-    LMT_ERROR,                              /* Erreur de traitement        */
-    LMT_WARNING,                            /* Avertissment à remonter     */
-
-    LMT_COUNT
-
-} LogMessageType;
-
 
 /* Indique le type définit pour un panneau d'affichage de messages. */
 GType g_log_panel_get_type(void);
@@ -76,10 +64,7 @@ GType g_log_panel_get_type(void);
 GPanelItem *g_log_panel_new(void);
 
 /* Affiche un message dans le journal des messages système. */
-void log_simple_message(LogMessageType, const char *);
-
-/* Affiche un message dans le journal des messages système. */
-void log_variadic_message(LogMessageType, const char *, ...);
+void g_log_panel_add_message(GLogPanel *, LogMessageType, const char *);
 
 
 
diff --git a/src/main.c b/src/main.c
index 1834352..20a443d 100644
--- a/src/main.c
+++ b/src/main.c
@@ -36,6 +36,7 @@
 #include "common/xdg.h"
 #include "core/core.h"
 #include "core/global.h"
+#include "core/logs.h"
 #include "core/params.h"
 #include "glibext/delayed.h"
 #include "gui/editor.h"
@@ -89,7 +90,8 @@ static void show_chrysalide_help(const char *name)
 
     printf("\n");
 
-    printf("\t--batch\t\tExit after processing files.\n");
+    printf("\t--verbosity=level\tSet the log level (0 for all messages, %u for none).\n", LMT_COUNT);
+    printf("\t--batch\t\t\tExit after processing files.\n");
 
     printf("\n");
 
@@ -145,6 +147,7 @@ int main(int argc, char **argv)
     int result;                             /* Bilan de l'exécution        */
     bool show_help;                         /* Affichage de l'aide ?       */
     bool show_version;                      /* Affichage de la version ?   */
+    LogMessageType verbosity;               /* Niveau de filtre de message */
     bool batch_mode;                        /* Exécution sans GUI ?        */
     int index;                              /* Indice d'argument           */
     int ret;                                /* Bilan d'un appel            */
@@ -160,10 +163,11 @@ int main(int argc, char **argv)
     bool welcome;                           /* Affichage de la bienvenue ? */
 
     static struct option long_options[] = {
-        { "help",       no_argument,    NULL,   'h' },
-        { "version",    no_argument,    NULL,   'v' },
-        { "batch",      no_argument,    NULL,   'b' },
-        { NULL,         0,              NULL,   0 }
+        { "help",       no_argument,        NULL,   'h' },
+        { "version",    no_argument,        NULL,   'v' },
+        { "verbosity",  required_argument,  NULL,   'V' },
+        { "batch",      no_argument,        NULL,   'b' },
+        { NULL,         0,                  NULL,   0 }
     };
 
     result = EXIT_FAILURE;
@@ -180,11 +184,12 @@ int main(int argc, char **argv)
     show_help = false;
     show_version = false;
 
+    verbosity = LMT_INFO;
     batch_mode = false;
 
     while (true)
     {
-        ret = getopt_long(argc, argv, "hvb", long_options, &index);
+        ret = getopt_long(argc, argv, "hvV:b", long_options, &index);
         if (ret == -1) break;
 
         switch (ret)
@@ -197,6 +202,10 @@ int main(int argc, char **argv)
                 show_version = true;
                 break;
 
+            case 'V':
+                verbosity = strtoul(optarg, NULL, 10);
+                break;
+
             case 'b':
                 batch_mode = true;
                 break;
@@ -235,6 +244,9 @@ int main(int argc, char **argv)
     gtk_init(&argc, &argv);
 
     /* Initialisation du programme */
+
+    set_log_verbosity(verbosity);
+
     if (!load_all_basic_components())
         return EXIT_FAILURE;
 
diff --git a/tests/core/logs.py b/tests/core/logs.py
new file mode 100644
index 0000000..96be519
--- /dev/null
+++ b/tests/core/logs.py
@@ -0,0 +1,34 @@
+#!/usr/bin/python3-dbg
+# -*- coding: utf-8 -*-
+
+
+# Tests validant le bon calcul d'empreintes.
+
+
+from chrysacase import ChrysalideTestCase
+from pychrysalide.core import logs
+
+
+class TestCoreLogs(ChrysalideTestCase):
+    """TestCase for analysis.core.logs."""
+
+    def testDefaultLevel(self):
+        """Ensure all messages are hidden by default."""
+
+        self.assertEqual(logs.get_verbosity(), logs.LMT_COUNT)
+
+
+    def testWrongLevel(self):
+        """Verify the type of level when defining new verbosity."""
+
+        with self.assertRaisesRegex(Exception, 'argument 1 must be int, not str'):
+
+            logs.set_verbosity('XXX')
+
+
+    def testWrongMessage(self):
+        """Check for unhandled message level."""
+
+        with self.assertRaisesRegex(Exception, 'Invalid type of message'):
+
+            logs.log_message(logs.LMT_COUNT, 'Message')
-- 
cgit v0.11.2-87-g4458