Looks fine to me. Thanks.

On Thu, Dec 5, 2013 at 5:02 PM, Ben Pfaff <b...@nicira.com> wrote:
> I sent out a revised version:
> http://openvswitch.org/pipermail/dev/2013-December/034644.html
>
> Will you look at it?
>
> On Tue, Dec 03, 2013 at 09:59:19PM -0800, Henry Mai wrote:
>> Sorry, found another violation where I had an extra newline before a 
>> function.
>>
>> On Tue, Dec 3, 2013 at 8:30 PM, Henry Mai <henry...@nicira.com> wrote:
>> > Another patch to address style issues
>> >
>> > On Tue, Dec 3, 2013 at 3:19 PM, Henry Mai <henry...@nicira.com> wrote:
>> >> Here's an updated patch.
>> >>
>> >> On Mon, Dec 2, 2013 at 2:06 PM, Ben Pfaff <b...@nicira.com> wrote:
>> >>> On Mon, Nov 25, 2013 at 11:08:15PM -0800, Henry Mai wrote:
>> >>>> Last patch got sent word wrapped, trying again.
>> >>>
>> >>>> This change allows vlog to export to a specified local udp syslog sink.
>> >>>>
>> >>>> Signed-off-by: Henry Mai <henry...@nicira.com>
>> >>>
>> >>> "sparse" says:
>> >>>
>> >>>     ../lib/vlog.c:887:10: warning: incorrect type in argument 5 
>> >>> (different base types)
>> >>>     ../lib/vlog.c:887:10:    expected struct sockaddr const *<noident>
>> >>>     ../lib/vlog.c:887:10:    got struct sockaddr_in *<noident>
>> >>>
>> >>> lib/vlog.man should document the new option.
>> >>>
>> >>> Lots of stuff mentioned in CodingStyle should be changed:
>> >>>
>> >>>         - Use /**/ not // for comments.
>> >>>
>> >>>         - Write comments as complete sentences that end in periods.
>> >>>
>> >>>         - Each function, and each variable declared outside a function
>> >>>           should be preceded by a comment.
>> >>>
>> >>>         - Put one blank line between top-level definitions of
>> >>>           functions and global variables.
>> >>>
>> >>>         - Put the return type, function name, and the braces that
>> >>>           surround the function's code on separate lines, all starting
>> >>>           in column 0.
>> >>>
>> >>> Please group the new static vars together rather than putting a
>> >>> prototype between them.
>> >>>
>> >>> This looks odd in our tree:
>> >>>     if (!error) {
>> >>>         loopback_mtu_size = mtu;
>> >>>     } // else it's just the default (1500)
>> >>> I'd be inclined to write it as:
>> >>>     if (!error) {
>> >>>         loopback_mtu_size = mtu;
>> >>>     } else {
>> >>>         /* Else it's just the default (1500). */
>> >>>     }
>> >>> or just:
>> >>>     loopback_mtu_size = !error ? mtu : 1500;
>> >>>
>> >>> Actually here's how I'd probably write the whole thing (you forgot to
>> >>> close the netdev, by the way):
>> >>>     error = netdev_open("lo", "system", &netdev);
>> >>>     if (!error) {
>> >>>         error = netdev_get_mtu(netdev, &mtu);
>> >>>         netdev_close(netdev);
>> >>>     }
>> >>>     loopback_mtu_size = !error ? mtu : 1500;
>> >>>
>> >>> This code looks expensive due to the big memset:
>> >>>             memset(hostname, 0, 255);
>> >>>             gethostname(hostname, 255);
>> >>>             ds_put_cstr(s, hostname);
>> >>> I know that gethostname() might not null-terminate if the hostname is
>> >>> too long but I think that the following is sufficent:
>> >>>             gethostname(hostname, sizeof hostname);
>> >>>             hostname[sizeof hostname - 1] = '\0';
>> >>>             ds_put_cstr(s, hostname);
>> >>>
>> >>> I am a little nervous about assuming that LOG_* has the same values
>> >>> required by RFC 5424.  I guess that the values will be correct for all
>> >>> Unix-like systems, but I am not sure that this assumption is warranted
>> >>> generally.
>> >>>
>> >>> This is indented funny:
>> >>> +    sendto(
>> >>> +        syslog_sink_fd,
>> >>> +        ds_cstr_ro(syslog_message),
>> >>> +        MIN(syslog_message->length, max_payload_size),
>> >>> +        0,
>> >>> +        &ipaddr,
>> >>> +        sizeof ipaddr);
>> >>> I would write it as:
>> >>>     sendto(syslog_sink_fd, ds_cstr_ro(syslog_message),
>> >>>            MIN(syslog_message->length, max_payload_size), 0,
>> >>>            &ipaddr, sizeof ipaddr);
>> >>>
>> >>> In vlog_valist(), it seems wasteful to format the message even if the
>> >>> formatted message will not be used (the common case).
>> >>>
>> >>> Thanks,
>> >>>
>> >>> Ben.
>
>> This change allows vlog to export to a specified local udp syslog sink.
>>
>> Signed-off-by: Henry Mai <henry...@nicira.com>
>> ---
>>  NEWS                      |   1 +
>>  lib/vlog.c                | 114 
>> ++++++++++++++++++++++++++++++++++++++++++++--
>>  lib/vlog.h                |  26 ++++++++---
>>  lib/vlog.man              |   4 ++
>>  utilities/ovs-appctl.8.in |   6 +++
>>  5 files changed, 141 insertions(+), 10 deletions(-)
>>
>> diff --git a/NEWS b/NEWS
>> index 38e3d9d..ede9338 100644
>> --- a/NEWS
>> +++ b/NEWS
>> @@ -23,6 +23,7 @@ Post-v2.0.0
>>       packaged or installed by default, because too many users assumed
>>       incorrectly that ovs-controller was a necessary or desirable part
>>       of an Open vSwitch deployment.
>> +   - Added vlog option to export to a local udp syslog sink.
>>
>>
>>  v2.0.0 - 15 Oct 2013
>> diff --git a/lib/vlog.c b/lib/vlog.c
>> index b1ca158..61d427d 100644
>> --- a/lib/vlog.c
>> +++ b/lib/vlog.c
>> @@ -23,6 +23,7 @@
>>  #include <stdarg.h>
>>  #include <stdlib.h>
>>  #include <string.h>
>> +#include <sys/socket.h>
>>  #include <sys/stat.h>
>>  #include <sys/types.h>
>>  #include <syslog.h>
>> @@ -32,8 +33,11 @@
>>  #include "coverage.h"
>>  #include "dirs.h"
>>  #include "dynamic-string.h"
>> +#include "netdev.h"
>>  #include "ofpbuf.h"
>> +#include "ovs-atomic.h"
>>  #include "ovs-thread.h"
>> +#include "packets.h"
>>  #include "sat-math.h"
>>  #include "svec.h"
>>  #include "timeval.h"
>> @@ -111,11 +115,29 @@ static int log_fd OVS_GUARDED_BY(log_file_mutex) = -1;
>>  static struct async_append *log_writer OVS_GUARDED_BY(log_file_mutex);
>>  static bool log_async OVS_GUARDED_BY(log_file_mutex);
>>
>> +/* Syslog export configuration. */
>> +static atomic_int udp_syslog_target_port = ATOMIC_VAR_INIT(0);
>> +static int loopback_mtu_size = 1500;
>> +static int syslog_sink_fd = -1;
>> +
>>  static void format_log_message(const struct vlog_module *, enum vlog_level,
>>                                 enum vlog_facility,
>>                                 const char *message, va_list, struct ds *)
>>      PRINTF_FORMAT(4, 0) OVS_REQ_RDLOCK(&pattern_rwlock);
>>
>> +/* Returns the equivalent rfc 5424 severity level. */
>> +static inline int
>> +get_5424_level(enum vlog_level level) {
>> +  switch (level) {
>> +    case VLL_EMER:     return 0;
>> +    case VLL_ERR:      return 3;
>> +    case VLL_WARN:     return 4;
>> +    case VLL_INFO:     return 6;
>> +    case VLL_DBG:      return 7;
>> +    default:           return 0;
>> +  }
>> +}
>> +
>>  /* Searches the 'n_names' in 'names'.  Returns the index of a match for
>>   * 'target', or 'n_names' if no name matches. */
>>  static size_t
>> @@ -480,6 +502,17 @@ vlog_set_verbosity(const char *arg)
>>      }
>>  }
>>
>> +/* Set the vlog udp syslog target port. */
>> +void
>> +vlog_set_syslog_target(const char *target)
>> +{
>> +    int value;
>> +    if (!str_to_int(target, 10, &value) || value < 0) {
>> +        value = 0;
>> +    }
>> +    atomic_store(&udp_syslog_target_port, value);
>> +}
>> +
>>  static void
>>  vlog_unixctl_set(struct unixctl_conn *conn, int argc, const char *argv[],
>>                   void *aux OVS_UNUSED)
>> @@ -582,6 +615,9 @@ vlog_init__(void)
>>  {
>>      static char *program_name_copy;
>>      long long int now;
>> +    struct netdev *netdev;
>> +    int error = 0;
>> +    int mtu = 0;
>>
>>      /* openlog() is allowed to keep the pointer passed in, without making a
>>       * copy.  The daemonize code sometimes frees and replaces 
>> 'program_name',
>> @@ -598,6 +634,10 @@ vlog_init__(void)
>>          free(s);
>>      }
>>
>> +    /* Ignore socket open failures, there is nothing else we can do about
>> +     * it. */
>> +    syslog_sink_fd = socket(AF_INET, SOCK_DGRAM, 0);
>> +
>>      unixctl_command_register(
>>          "vlog/set", "{spec | PATTERN:facility:pattern}",
>>          1, INT_MAX, vlog_unixctl_set, NULL);
>> @@ -608,6 +648,13 @@ vlog_init__(void)
>>                               0, INT_MAX, vlog_disable_rate_limit, NULL);
>>      unixctl_command_register("vlog/reopen", "", 0, 0,
>>                               vlog_unixctl_reopen, NULL);
>> +
>> +    error = netdev_open("lo", "system", &netdev);
>> +    if (!error) {
>> +        error = netdev_get_mtu(netdev, &mtu);
>> +        netdev_close(netdev);
>> +    }
>> +    loopback_mtu_size = !error ? mtu : 1500;
>>  }
>>
>>  /* Initializes the logging subsystem and registers its unixctl server
>> @@ -703,7 +750,10 @@ format_log_message(const struct vlog_module *module, 
>> enum vlog_level level,
>>                     enum vlog_facility facility,
>>                     const char *message, va_list args_, struct ds *s)
>>  {
>> +    static const int local0_facility = 16;
>> +
>>      char tmp[128];
>> +    char hostname[255];
>>      va_list args;
>>      const char *p;
>>
>> @@ -739,6 +789,10 @@ format_log_message(const struct vlog_module *module, 
>> enum vlog_level level,
>>          case 'A':
>>              ds_put_cstr(s, program_name);
>>              break;
>> +        case 'B':
>> +            ds_put_format(s, "%d",
>> +                ((local0_facility << 3) + get_5424_level(level)));
>> +            break;
>>          case 'c':
>>              p = fetch_braces(p, "", tmp, sizeof tmp);
>>              ds_put_cstr(s, vlog_get_module_name(module));
>> @@ -751,6 +805,11 @@ format_log_message(const struct vlog_module *module, 
>> enum vlog_level level,
>>              p = fetch_braces(p, "%Y-%m-%d %H:%M:%S.###", tmp, sizeof tmp);
>>              ds_put_strftime_msec(s, tmp, time_wall_msec(), true);
>>              break;
>> +        case 'E':
>> +            gethostname(hostname, 255);
>> +            hostname[sizeof hostname - 1] = '\0';
>> +            ds_put_cstr(s, hostname);
>> +            break;
>>          case 'm':
>>              /* Format user-supplied log message and trim trailing 
>> new-lines. */
>>              length = s->length;
>> @@ -804,6 +863,43 @@ format_log_message(const struct vlog_module *module, 
>> enum vlog_level level,
>>      }
>>  }
>>
>> +/* Returns whether or not udp syslog export is enabled.
>> + * Sets the 'target_udp_port_out' parameter with the target udp port
>> + * if enabled. */
>> +static bool
>> +udp_syslog_export_enabled(int *target_udp_port_out)
>> +{
>> +    bool enabled = false;
>> +    int target_udp_port;
>> +    atomic_read(&udp_syslog_target_port, &target_udp_port);
>> +    enabled = ((target_udp_port > 0 ) && (syslog_sink_fd >= 0));
>> +    if (enabled) {
>> +        *target_udp_port_out = target_udp_port;
>> +    }
>> +    return enabled;
>> +}
>> +
>> +/* Exports the given 'syslog_message' to the configured local udp syslog
>> + * sink. */
>> +static void
>> +export_to_udp_syslog_target(struct ds *syslog_message, int target_udp_port)
>> +{
>> +    static const int ipv4_udp_header_size = IP_HEADER_LEN + UDP_HEADER_LEN;
>> +    int max_payload_size;
>> +    struct sockaddr_in ipaddr;
>> +
>> +    memset(&ipaddr, 0, sizeof ipaddr);
>> +
>> +    ipaddr.sin_family = AF_INET;
>> +    ipaddr.sin_port = htons(target_udp_port);
>> +    inet_pton(AF_INET, "127.0.0.1", &ipaddr.sin_addr);
>> +
>> +    max_payload_size = loopback_mtu_size - ipv4_udp_header_size;
>> +    sendto(syslog_sink_fd, ds_cstr_ro(syslog_message),
>> +        MIN(syslog_message->length, max_payload_size), 0,
>> +        (struct sockaddr *)(&ipaddr), sizeof ipaddr);
>> +}
>> +
>>  /* Writes 'message' to the log at the given 'level' and as coming from the
>>   * given 'module'.
>>   *
>> @@ -837,6 +933,7 @@ vlog_valist(const struct vlog_module *module, enum 
>> vlog_level level,
>>          }
>>
>>          if (log_to_syslog) {
>> +            int target_udp_port = 0;
>>              int syslog_level = syslog_levels[level];
>>              char *save_ptr = NULL;
>>              char *line;
>> @@ -846,6 +943,12 @@ vlog_valist(const struct vlog_module *module, enum 
>> vlog_level level,
>>                   line = strtok_r(NULL, "\n", &save_ptr)) {
>>                  syslog(syslog_level, "%s", line);
>>              }
>> +
>> +            if (udp_syslog_export_enabled(&target_udp_port)) {
>> +                format_log_message(
>> +                    module, level, VLF_RFC5424, message, args, &s);
>> +                export_to_udp_syslog_target(&s, target_udp_port);
>> +            }
>>          }
>>
>>          if (log_to_file) {
>> @@ -1013,9 +1116,12 @@ void
>>  vlog_usage(void)
>>  {
>>      printf("\nLogging options:\n"
>> -           "  -v, --verbose=[SPEC]    set logging levels\n"
>> -           "  -v, --verbose           set maximum verbosity level\n"
>> -           "  --log-file[=FILE]       enable logging to specified FILE\n"
>> -           "                          (default: %s/%s.log)\n",
>> +           "  -v, --verbose=[SPEC]       set logging levels\n"
>> +           "  -v, --verbose              set maximum verbosity level\n"
>> +           "  --log-file[=FILE]          enable logging to specified FILE\n"
>> +           "                             (default: %s/%s.log)\n"
>> +           "  --syslog-target=[UDP_PORT] export syslog messages to the \n"
>> +           "                             local UDP_PORT in addition to \n"
>> +           "                             the system syslog\n",
>>             ovs_logdir(), program_name);
>>  }
>> diff --git a/lib/vlog.h b/lib/vlog.h
>> index d7d63bf..05c65a8 100644
>> --- a/lib/vlog.h
>> +++ b/lib/vlog.h
>> @@ -62,9 +62,11 @@ enum vlog_level vlog_get_level_val(const char *name);
>>
>>  /* Facilities that we can log to. */
>>  #define VLOG_FACILITIES                                                 \
>> -    VLOG_FACILITY(SYSLOG, "ovs|%05N|%c%T|%p|%m")                            
>> \
>> +    VLOG_FACILITY(SYSLOG, "ovs|%05N|%c%T|%p|%m")                        \
>>      VLOG_FACILITY(CONSOLE, "%D{%Y-%m-%dT%H:%M:%SZ}|%05N|%c%T|%p|%m")    \
>> -    VLOG_FACILITY(FILE, "%D{%Y-%m-%dT%H:%M:%S.###Z}|%05N|%c%T|%p|%m")
>> +    VLOG_FACILITY(FILE, "%D{%Y-%m-%dT%H:%M:%S.###Z}|%05N|%c%T|%p|%m")   \
>> +    VLOG_FACILITY(RFC5424,                                              \
>> +        "<%B>1 %D{%Y-%m-%dT%H:%M:%S.###Z} %E %A %P %c - \xEF\xBB\xBF%m")
>>  enum vlog_facility {
>>  #define VLOG_FACILITY(NAME, PATTERN) VLF_##NAME,
>>      VLOG_FACILITIES
>> @@ -139,6 +141,9 @@ void vlog_set_pattern(enum vlog_facility, const char 
>> *pattern);
>>  int vlog_set_log_file(const char *file_name);
>>  int vlog_reopen_log_file(void);
>>
>> +/* Configure syslog target. */
>> +void vlog_set_syslog_target(const char *target);
>> +
>>  /* Initialization. */
>>  void vlog_init(void);
>>  void vlog_enable_async(void);
>> @@ -213,17 +218,26 @@ void vlog_rate_limit(const struct vlog_module *, enum 
>> vlog_level,
>>  #define VLOG_DBG_ONCE(...) VLOG_ONCE(VLL_DBG, __VA_ARGS__)
>>
>>  /* Command line processing. */
>> -#define VLOG_OPTION_ENUMS OPT_LOG_FILE
>> -#define VLOG_LONG_OPTIONS                                   \
>> -        {"verbose",     optional_argument, NULL, 'v'},         \
>> -        {"log-file",    optional_argument, NULL, OPT_LOG_FILE}
>> +#define VLOG_OPTION_ENUMS \
>> +  OPT_LOG_FILE, \
>> +  OPT_SYSLOG_TARGET
>> +
>> +#define VLOG_LONG_OPTIONS                                        \
>> +    {"verbose",       optional_argument, NULL, 'v'},             \
>> +    {"log-file",      optional_argument, NULL, OPT_LOG_FILE},     \
>> +    {"syslog-target", optional_argument, NULL, OPT_SYSLOG_TARGET}
>> +
>>  #define VLOG_OPTION_HANDLERS                    \
>>          case 'v':                               \
>>              vlog_set_verbosity(optarg);         \
>>              break;                              \
>>          case OPT_LOG_FILE:                      \
>>              vlog_set_log_file(optarg);          \
>> +            break;                              \
>> +        case OPT_SYSLOG_TARGET:                 \
>> +            vlog_set_syslog_target(optarg);     \
>>              break;
>> +
>>  void vlog_usage(void);
>>
>>  /* Implementation details. */
>> diff --git a/lib/vlog.man b/lib/vlog.man
>> index 39edaee..1410394 100644
>> --- a/lib/vlog.man
>> +++ b/lib/vlog.man
>> @@ -60,3 +60,7 @@ Sets the log pattern for \fIfacility\fR to \fIpattern\fR.  
>> Refer to
>>  Enables logging to a file.  If \fIfile\fR is specified, then it is
>>  used as the exact name for the log file.  The default log file name
>>  used if \fIfile\fR is omitted is \fB@LOGDIR@/\*(PN.log\fR.
>> +.TP
>> +\fB\-\-syslog\-target\fR[\fB=\fIudp_port\fR]
>> +export syslog messages to the local \fIudp_port\fR in addition to the
>> +system syslog.
>> diff --git a/utilities/ovs-appctl.8.in b/utilities/ovs-appctl.8.in
>> index 1cf888d..e381b2b 100644
>> --- a/utilities/ovs-appctl.8.in
>> +++ b/utilities/ovs-appctl.8.in
>> @@ -148,6 +148,9 @@ expanded as follows:
>>  .IP \fB%A\fR
>>  The name of the application logging the message, e.g. \fBovs\-vswitchd\fR.
>>  .
>> +.IP \fB%B\fR
>> +The RFC5424 syslog PRI of the message.
>> +.
>>  .IP \fB%c\fR
>>  The name of the module (as shown by \fBovs\-appctl \-\-list\fR) logging
>>  the message.
>> @@ -173,6 +176,9 @@ takes the same format as the \fItemplate\fR argument to
>>  \fBstrftime\fR(3).  Supports the same extension for sub-second
>>  resolution as \fB%d{\fR...\fB}\fR.
>>  .
>> +.IP \fB%E\fR
>> +The hostname of the node running the application.
>> +.
>>  .IP \fB%m\fR
>>  The message being logged.
>>  .
>> --
>> 1.8.5.rc1.17.g0ecd94d
>>
>
_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to