forked from openvswitch/ovs
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
vlog: abstract out interface to syslog daemon
This patch helps to address two issues that are present on Ubuntu 15.04 (and most likely other Linux distributions) where rsyslog daemon is configured to relay log messages from OVS to a remote log collector and syslog format being used is something other than the one defined in RFC 3164. These two issues are: 1. libc syslog() function always adds RFC 3164 prefix to syslog messages before sending them over /dev/log Unix domain socket. This does not allow us to use libc syslog() function to log in RFC 5424 format; and 2. rsyslogd daemon that comes with Ubuntu 15.04 is too old and uses hardcoded syslog message parser when it received messages over /dev/log UNIX domain socket. Solution to those two issues would be to use the newly introduced --syslog-method=udp:127.0.0.1:514 command line argument when starting OVS. Signed-off-by: Ansis Atteka <[email protected]> Acked-by: Ben Pfaff <[email protected]>
- Loading branch information
Ansis Atteka
committed
Jun 27, 2015
1 parent
5bb08b0
commit fe089c0
Showing
10 changed files
with
351 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
/* | ||
* Copyright (c) 2015 Nicira, Inc. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at: | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
#include "syslog-direct.h" | ||
|
||
#include <config.h> | ||
|
||
#include <string.h> | ||
#include <unistd.h> | ||
|
||
#include "compiler.h" | ||
#include "dynamic-string.h" | ||
#include "socket-util.h" | ||
#include "syslog-provider.h" | ||
#include "util.h" | ||
|
||
#define FACILITY_MASK 0x03f8 | ||
|
||
static void syslog_direct_open(struct syslogger *this, int facility); | ||
static void syslog_direct_log(struct syslogger *this, int pri, | ||
const char *msg); | ||
|
||
static struct syslog_class syslog_direct_class = { | ||
syslog_direct_open, | ||
syslog_direct_log, | ||
}; | ||
|
||
struct syslog_direct { | ||
struct syslogger parent; | ||
int fd; /* Negative number in error case. Otherwise, socket. */ | ||
int facility; | ||
}; | ||
|
||
|
||
/* This function creates object that directly interacts with syslog over | ||
* UDP or Unix domain socket specified in 'method'. */ | ||
struct syslogger * | ||
syslog_direct_create(const char *method) | ||
{ | ||
struct syslog_direct *this = xmalloc(sizeof *this); | ||
|
||
this->parent.class = &syslog_direct_class; | ||
this->parent.prefix = "<%B>"; | ||
|
||
/* socket is created from here (opposed to syslog_direct_open()) | ||
* so that deadlocks would be avoided. The problem is that these | ||
* functions that create socket might call VLOG() */ | ||
if (!strncmp(method, "udp:", 4)) { | ||
inet_open_active(SOCK_DGRAM, &method[4], 514, NULL, &this->fd, 0); | ||
} else if (!strncmp(method, "unix:", 5)) { | ||
this->fd = make_unix_socket(SOCK_DGRAM, true, NULL, &method[5]); | ||
} else { | ||
this->fd = -1; | ||
} | ||
|
||
return &this->parent; | ||
} | ||
|
||
static void | ||
syslog_direct_open(struct syslogger *this, int facility) | ||
{ | ||
struct syslog_direct *this_ = (struct syslog_direct*) this; | ||
|
||
this_->facility = facility; | ||
} | ||
|
||
static void | ||
syslog_direct_log(struct syslogger *this, int pri, const char *msg) | ||
{ | ||
static size_t max_len = SIZE_MAX; /* max message size we have discovered | ||
* to be able to send() without failing | ||
* with EMSGSIZE. */ | ||
|
||
struct syslog_direct *this_ = (struct syslog_direct*) this; | ||
struct ds ds = DS_EMPTY_INITIALIZER; | ||
const char *wire_msg; | ||
size_t send_len; | ||
|
||
if (this_->fd < 0) { | ||
/* Failed to open socket for logging. */ | ||
return; | ||
} | ||
|
||
if (!(pri & FACILITY_MASK)) { | ||
pri |= this_->facility; | ||
} | ||
ds_put_format(&ds, "<%u>%s", pri, msg); | ||
wire_msg = ds_cstr(&ds); | ||
send_len = MIN(strlen(wire_msg), max_len);; | ||
while (send(this_->fd, wire_msg, send_len, 0) < 0 && errno == EMSGSIZE) { | ||
/* If message was too large for send() function then try to discover | ||
* max_len supported for this particular socket and retry sending a | ||
* truncated version of the same message. */ | ||
send_len -= send_len / 20; | ||
max_len = send_len; | ||
} | ||
ds_destroy(&ds); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
/* | ||
* Copyright (c) 2015 Nicira, Inc. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at: | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
#ifndef SYSLOG_DIRECT_H | ||
#define SYSLOG_DIRECT_H 1 | ||
|
||
struct syslogger *syslog_direct_create(const char *method); | ||
|
||
#endif /* syslog-direct.h */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
/* | ||
* Copyright (c) 2015 Nicira, Inc. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at: | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
#include "syslog-libc.h" | ||
|
||
#include <config.h> | ||
|
||
#include <string.h> | ||
#include <syslog.h> | ||
#include <unistd.h> | ||
|
||
#include "compiler.h" | ||
#include "dynamic-string.h" | ||
#include "socket-util.h" | ||
#include "syslog-provider.h" | ||
#include "util.h" | ||
|
||
|
||
static void syslog_libc_open(struct syslogger *this, int facility); | ||
static void syslog_libc_log(struct syslogger *this, int pri, const char *msg); | ||
|
||
static struct syslog_class syslog_libc_class = { | ||
syslog_libc_open, | ||
syslog_libc_log, | ||
}; | ||
|
||
struct syslog_libc { | ||
struct syslogger parent; | ||
}; | ||
|
||
|
||
/* This function creates object that delegate all logging to libc's | ||
* syslog implementation. */ | ||
struct syslogger * | ||
syslog_libc_create(void) | ||
{ | ||
struct syslog_libc *this = xmalloc(sizeof *this); | ||
|
||
this->parent.class = &syslog_libc_class; | ||
this->parent.prefix = "<%B> %D{%h %e %T} %E %A:"; | ||
|
||
return &this->parent; | ||
} | ||
|
||
static void | ||
syslog_libc_open(struct syslogger *this OVS_UNUSED, int facility) | ||
{ | ||
static char *ident; | ||
|
||
/* openlog() is allowed to keep the pointer passed in, without making a | ||
* copy. The daemonize code sometimes frees and replaces | ||
* 'program_name', so make a private copy just for openlog(). (We keep | ||
* a pointer to the private copy to suppress memory leak warnings in | ||
* case openlog() does make its own copy.) */ | ||
ident = program_name ? xstrdup(program_name) : NULL; | ||
|
||
openlog(ident, LOG_NDELAY, facility); | ||
} | ||
|
||
static void | ||
syslog_libc_log(struct syslogger *this OVS_UNUSED, int pri, const char *msg) | ||
{ | ||
syslog(pri, "%s", msg); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
/* | ||
* Copyright (c) 2015 Nicira, Inc. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at: | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
#ifndef SYSLOG_LIBC_H | ||
#define SYSLOG_LIBC_H 1 | ||
|
||
struct syslogger *syslog_libc_create(void); | ||
|
||
#endif /* syslog-libc.h */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
/* | ||
* Copyright (c) 2015 Nicira, Inc. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at: | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
#ifndef SYSLOG_PROVIDER_H | ||
#define SYSLOG_PROVIDER_H 1 | ||
|
||
|
||
/* Open vSwitch interface to syslog daemon's interface. | ||
* | ||
* 'syslogger' is the base class that provides abstraction. */ | ||
struct syslogger { | ||
const struct syslog_class *class; /* Virtual functions for concrete | ||
* syslogger implementations. */ | ||
const char *prefix; /* Prefix that is enforced by concrete | ||
* syslogger implementation. Used | ||
* in vlog/list-pattern function. */ | ||
}; | ||
|
||
/* Each concrete syslogger implementation must define it's own table with | ||
* following functions. These functions must never call any other VLOG_ | ||
* function to prevent deadlocks. */ | ||
struct syslog_class { | ||
/* openlog() function should be called before syslog() function. It | ||
* should initialize all system resources needed to perform logging. */ | ||
void (*openlog)(struct syslogger *this, int facility); | ||
|
||
/* syslog() function sends message 'msg' to syslog daemon. */ | ||
void (*syslog)(struct syslogger *this, int pri, const char *msg); | ||
}; | ||
|
||
static inline const char * | ||
syslog_get_prefix(struct syslogger *this) | ||
{ | ||
return this->prefix; | ||
} | ||
|
||
#endif /* syslog-provider.h */ |
Oops, something went wrong.