On 02/07/2013 02:12 PM, Peter Schiffer wrote:
> Whole new logging with following goals is here:
>  - more log levels.
>  - allow applications to log somewhere else than stdout using their custom
>    callback.
>  - provide simple stdout logger for 'lazy' applications.
> 
> The logging is off by default, i.e. no message appears on stdout unless
> application initializes the logging explicitly. But see following patches!
> 
> Internally, nothing changes, cgroup_dbg is still working. In addition,
> cgroup_err, cgroup_warn and cgroup_info appeared. Description what message
> should use which log level is in doxygen info, together with new public API
> incl. simple example, I won't copy it here
> 
> Also the cgroup_log function is made public. I am not sure if it is the
> right thing to do, but that's currently the simplest way how to use the
> logging from our tools (which link only the public libcgroup API).
> 
> Changelog:
>   - fixed typo in cgroup_log doxygen comment
> 
> Signed-off-by: Peter Schiffer <pschi...@redhat.com>
> ---
>  include/Makefile.am      |    2 -
>  include/libcgroup.h      |    1 
>  include/libcgroup/log.h  |  138 
> ++++++++++++++++++++++++++++++++++++++++++++++
>  src/Makefile.am          |    2 -
>  src/libcgroup-internal.h |    8 ++-
>  src/libcgroup.map        |    4 +
>  src/log.c                |   76 +++++++++++++++++++++++++
>  7 files changed, 228 insertions(+), 3 deletions(-)
>  create mode 100644 include/libcgroup/log.h
>  create mode 100644 src/log.c
> 
> diff --git a/include/Makefile.am b/include/Makefile.am
> index a7602a9..752a624 100644
> --- a/include/Makefile.am
> +++ b/include/Makefile.am
> @@ -1,2 +1,2 @@
>  # Using 'nobase_', we what groups.h in /usr/include/libcgroup/ directory
> -nobase_include_HEADERS = libcgroup.h libcgroup/error.h libcgroup/init.h 
> libcgroup/groups.h libcgroup/tasks.h libcgroup/iterators.h libcgroup/config.h
> +nobase_include_HEADERS = libcgroup.h libcgroup/error.h libcgroup/init.h 
> libcgroup/groups.h libcgroup/tasks.h libcgroup/iterators.h libcgroup/config.h 
> libcgroup/log.h
> diff --git a/include/libcgroup.h b/include/libcgroup.h
> index 543bd13..1c7d409 100644
> --- a/include/libcgroup.h
> +++ b/include/libcgroup.h
> @@ -24,6 +24,7 @@
>  #include <libcgroup/groups.h>
>  #include <libcgroup/tasks.h>
>  #include <libcgroup/config.h>
> +#include <libcgroup/log.h>
>  
>  #undef _LIBCGROUP_H_INSIDE
>  
> diff --git a/include/libcgroup/log.h b/include/libcgroup/log.h
> new file mode 100644
> index 0000000..cd4f11d
> --- /dev/null
> +++ b/include/libcgroup/log.h
> @@ -0,0 +1,138 @@
> +#ifndef _LIBCGROUP_LOG_H
> +#define _LIBCGROUP_LOG_H
> +
> +#ifndef _LIBCGROUP_H_INSIDE
> +#error "Only <libcgroup.h> should be included directly."
> +#endif
> +
> +#ifndef SWIG
> +#include <features.h>
> +#endif
> +
> +#include <stdarg.h>
> +
> +__BEGIN_DECLS
> +
> +/**
> + * @defgroup group_log 7. Logging
> + * @{
> + *
> + * @name Logging
> + * @{
> + * Libcgroup allows applications to register a callback function which
> + * libcgroup will call when it wants to log something. Each log message
> + * has associated a log level. As described in previous chapter, most 
> libcgroup
> + * functions return an error code, which described root cause of the failure
> + * and log messages might provide further details about these failures and 
> other
> + * notable events.
> + *
> + * @par
> + * The logging callback can be set at any time, but setting the callback 
> before
> + * any other libcgroup function (including cgroup_init()) is highly 
> recommended.
> + *
> + * @par Setting log level
> + * Some of the functions below set the log level as integer.
> + * Application can set directly a value of enum #cgroup_log_level or use
> + * value <tt>-1</tt> to set the log level automatically. In this case, 
> libcgroup
> + * inspects environment variable <tt>CGROUP_LOGLEVEL</tt> if it is set
> + * and contains any of these values: <tt>ERROR</tt>, <tt>WARNING</tt>,
> + * <tt>INFO</tt>, <tt>DEBUG</tt> or integer number representing value from
> + * enum #cgroup_log_level. If <tt>CGROUP_LOGLEVEL</tt> is not set or its 
> value
> + * is not valid, <tt>CGROUP_LOG_WARNING</tt> is set as default log level.

If I read the patches correctly, the default is now CGROUP_LOG_ERROR and
not CGROUP_LOG_WARNING.

Otherwise, Acked-By: Jan Safranek <jsafr...@redhat.com>

> + *
> + * @par Example:
> + * Following short example shows custom libcgroup logger sending all log
> + * messages to <tt>stderr</tt>:
> + * @code
> + * static void my_logger(void *userdata, int level, const char *fmt, va_list 
> ap)
> + * {
> + *   vfprintf(stderr, fmt, ap);
> + * }
> + *
> + * int main(int argc, char **argv)
> + * {
> + *   int ret;
> + *
> + *   cgroup_set_logger(my_logger, -1, NULL);
> + *   ret = cgroup_init();
> + *   if (ret) {
> + *           ...
> + *   }
> + *   ...
> + * @endcode
> + */
> +
> +/**
> + * Level of importance of a log message.
> + */
> +enum cgroup_log_level {
> +     /**
> +      * Something serious happened and libcgroup failed to perform requested
> +      * operation.
> +      */
> +     CGROUP_LOG_ERROR = 1,
> +     /**
> +      * Something bad happened but libcgroup recovered from the error.
> +      */
> +     CGROUP_LOG_WARNING,
> +     /**
> +      * Something interesting happened and the message might be useful to the
> +      * user.
> +      */
> +     CGROUP_LOG_INFO,
> +     /**
> +      * Debugging messages useful to libcgroup developers.
> +      */
> +     CGROUP_LOG_DEBUG,
> +};
> +
> +typedef void (*cgroup_logger_callback)(void *userdata, int level,
> +             const char *fmt, va_list ap);
> +
> +/**
> + * Set libcgroup logging callback. All log messages with equal or lower log
> + * level will be sent to the application's callback. There can be only
> + * one callback logger set, the previous callback is replaced with the new 
> one
> + * by calling this function.
> + * Use NULL as the logger callback to completely disable libcgroup logging.
> + *
> + * @param logger The callback.
> + * @param loglevel The log level. Use value -1 to automatically discover the
> + * level from CGROUP_LOGLEVEL environment variable.
> + * @param userdata Application's data which will be provided back to the
> + * callback.
> + */
> +extern void cgroup_set_logger(cgroup_logger_callback logger, int loglevel,
> +             void *userdata);
> +
> +/**
> + * Set libcgroup logging to stdout. All messages with the given loglevel
> + * or below will be sent to standard output. Previous logger set by
> + * cgroup_set_logger() is replaced.
> + *
> + * @param loglevel The log level. Use value -1 to automatically discover the
> + * level from CGROUP_LOGLEVEL environment variable.
> + */
> +extern void cgroup_set_default_logger(int loglevel);
> +
> +/**
> + * Change current loglevel.
> + * @param loglevel The log level. Use value -1 to automatically discover the
> + * level from CGROUP_LOGLEVEL environment variable.
> + */
> +extern void cgroup_set_loglevel(int loglevel);
> +
> +/**
> + * Libcgroup log function. This is for applications which are too lazy to set
> + * up their own complex logging and miss-use libcgroup for that purpose.
> + * I.e. this function should be used only by simple command-line tools.
> + * This logging automatically benefits from CGROUP_LOGLEVEL env. variable.
> + */
> +extern void cgroup_log(int loglevel, const char *fmt, ...);
> +/**
> + * @}
> + * @}
> + */
> +__END_DECLS
> +
> +#endif /* _LIBCGROUP_LOG_H */
> diff --git a/src/Makefile.am b/src/Makefile.am
> index 18a2ef0..3a92d59 100644
> --- a/src/Makefile.am
> +++ b/src/Makefile.am
> @@ -11,7 +11,7 @@ CLEANFILES = lex.c parse.c parse.h
>  
>  INCLUDES = -I$(top_srcdir)/include
>  lib_LTLIBRARIES = libcgroup.la
> -libcgroup_la_SOURCES = parse.h parse.y lex.l api.c config.c 
> libcgroup-internal.h libcgroup.map wrapper.c
> +libcgroup_la_SOURCES = parse.h parse.y lex.l api.c config.c 
> libcgroup-internal.h libcgroup.map wrapper.c log.c
>  libcgroup_la_LIBADD = -lpthread
>  libcgroup_la_LDFLAGS = -Wl,--version-script,$(srcdir)/libcgroup.map \
>       -version-number 
> $(LIBRARY_VERSION_MAJOR):$(LIBRARY_VERSION_MINOR):$(LIBRARY_VERSION_RELEASE)
> diff --git a/src/libcgroup-internal.h b/src/libcgroup-internal.h
> index dbb8e9a..47ee2ab 100644
> --- a/src/libcgroup-internal.h
> +++ b/src/libcgroup-internal.h
> @@ -61,12 +61,18 @@ __BEGIN_DECLS
>  #define CGROUP_RULE_MAXLINE  (FILENAME_MAX + CGROUP_RULE_MAXKEY + \
>       CG_CONTROLLER_MAX + 3)
>  
> +#define cgroup_err(x...) cgroup_log(CGROUP_LOG_ERROR, x)
> +#define cgroup_warn(x...) cgroup_log(CGROUP_LOG_WARNING, x)
> +#define cgroup_info(x...) cgroup_log(CGROUP_LOG_INFO, x)
> +
>  #ifdef CGROUP_DEBUG
> -#define cgroup_dbg(x...) printf(x)
> +#define cgroup_dbg(x...) cgroup_log(CGROUP_LOG_DEBUG, x)
>  #else
>  #define cgroup_dbg(x...) do {} while (0)
>  #endif
>  
> +#define CGROUP_DEFAULT_LOGLEVEL CGROUP_LOG_ERROR
> +
>  #define max(x,y) ((y)<(x)?(x):(y))
>  #define min(x,y) ((y)>(x)?(x):(y))
>  
> diff --git a/src/libcgroup.map b/src/libcgroup.map
> index b550a58..fc850b3 100644
> --- a/src/libcgroup.map
> +++ b/src/libcgroup.map
> @@ -110,4 +110,8 @@ CGROUP_0.39 {
>       cgroup_reload_cached_templates;
>       cgroup_init_templates_cache;
>       cgroup_config_create_template_group;
> +     cgroup_set_logger;
> +     cgroup_set_default_logger;
> +     cgroup_set_loglevel;
> +     cgroup_log;
>  } CGROUP_0.38;
> diff --git a/src/log.c b/src/log.c
> new file mode 100644
> index 0000000..d0a6854
> --- /dev/null
> +++ b/src/log.c
> @@ -0,0 +1,76 @@
> +/*
> + * Copyright Red Hat, Inc. 2012
> + *
> + * Author:   Jan Safranek <jsafr...@redhat.com>
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms of version 2.1 of the GNU Lesser General Public License
> + * as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it would be useful, but
> + * WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
> + */
> +
> +#include <libcgroup.h>
> +#include <libcgroup-internal.h>
> +#include <stdarg.h>
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <errno.h>
> +
> +static cgroup_logger_callback cgroup_logger;
> +static void *cgroup_logger_userdata;
> +static int cgroup_loglevel;
> +
> +static void cgroup_default_logger(void *userdata, int level, const char *fmt,
> +                               va_list ap)
> +{
> +     vfprintf(stdout, fmt, ap);
> +}
> +
> +void cgroup_log(int level, const char *fmt, ...)
> +{
> +     va_list ap;
> +
> +     if (!cgroup_logger)
> +             return;
> +
> +     if (level > cgroup_loglevel)
> +             return;
> +
> +     va_start(ap, fmt);
> +     cgroup_logger(cgroup_logger_userdata, level, fmt, ap);
> +     va_end(ap);
> +}
> +
> +void cgroup_set_logger(cgroup_logger_callback logger, int loglevel,
> +             void *userdata)
> +{
> +     cgroup_logger = logger;
> +     cgroup_set_loglevel(loglevel);
> +     cgroup_logger_userdata = userdata;
> +}
> +
> +void cgroup_set_default_logger(int level)
> +{
> +     if (!cgroup_logger)
> +             cgroup_set_logger(cgroup_default_logger, level, NULL);
> +}
> +
> +void cgroup_set_loglevel(int loglevel)
> +{
> +     if (loglevel != -1)
> +             cgroup_loglevel = loglevel;
> +     else {
> +             char *level_str = getenv("CGROUP_LOGLEVEL");
> +             if (level_str != NULL)
> +                     /*
> +                      * TODO: add better loglevel detection, e.g. strings
> +                      * instead of plain numbers.
> +                      */
> +                     cgroup_loglevel = atoi(level_str);
> +             else
> +                     cgroup_loglevel = CGROUP_DEFAULT_LOGLEVEL;
> +     }
> +}
> 
> 
> ------------------------------------------------------------------------------
> Free Next-Gen Firewall Hardware Offer
> Buy your Sophos next-gen firewall before the end March 2013 
> and get the hardware for free! Learn more.
> http://p.sf.net/sfu/sophos-d2d-feb
> _______________________________________________
> Libcg-devel mailing list
> Libcg-devel@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/libcg-devel
> 


------------------------------------------------------------------------------
Free Next-Gen Firewall Hardware Offer
Buy your Sophos next-gen firewall before the end March 2013 
and get the hardware for free! Learn more.
http://p.sf.net/sfu/sophos-d2d-feb
_______________________________________________
Libcg-devel mailing list
Libcg-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/libcg-devel

Reply via email to