Added support for multiple syslog channels.
This commit is contained in:
parent
dc31b4f1c1
commit
f13adbe4bb
@ -17,6 +17,12 @@ config SYSLOG_WRITE
|
|||||||
bool
|
bool
|
||||||
default n
|
default n
|
||||||
|
|
||||||
|
config SYSLOG_MAX_CHANNELS
|
||||||
|
int "Maximum SYSLOG channels"
|
||||||
|
default 1
|
||||||
|
---help---
|
||||||
|
Maximum number of supported SYSLOG channels.
|
||||||
|
|
||||||
config RAMLOG
|
config RAMLOG
|
||||||
bool "RAM log device support"
|
bool "RAM log device support"
|
||||||
default n
|
default n
|
||||||
|
@ -48,7 +48,8 @@ extern "C"
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
struct syslog_channel_s; /* Forward reference */
|
struct syslog_channel_s; /* Forward reference */
|
||||||
EXTERN FAR const struct syslog_channel_s *g_syslog_channel;
|
EXTERN FAR const struct syslog_channel_s *g_syslog_channel
|
||||||
|
[CONFIG_SYSLOG_MAX_CHANNELS];
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Function Prototypes
|
* Public Function Prototypes
|
||||||
@ -216,7 +217,6 @@ int syslog_add_intbuffer(int ch);
|
|||||||
* to the SYSLOG device.
|
* to the SYSLOG device.
|
||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* channel - The syslog channel to use in performing the flush operation.
|
|
||||||
* force - Use the force() method of the channel vs. the putc() method.
|
* force - Use the force() method of the channel vs. the putc() method.
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* Returned Value:
|
||||||
@ -229,8 +229,7 @@ int syslog_add_intbuffer(int ch);
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#ifdef CONFIG_SYSLOG_INTBUFFER
|
#ifdef CONFIG_SYSLOG_INTBUFFER
|
||||||
int syslog_flush_intbuffer(FAR const struct syslog_channel_s *channel,
|
int syslog_flush_intbuffer(bool force);
|
||||||
bool force);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
|
@ -92,7 +92,11 @@ static const struct syslog_channel_s g_default_channel =
|
|||||||
|
|
||||||
/* This is the current syslog channel in use */
|
/* This is the current syslog channel in use */
|
||||||
|
|
||||||
FAR const struct syslog_channel_s *g_syslog_channel = &g_default_channel;
|
FAR const struct syslog_channel_s
|
||||||
|
*g_syslog_channel[CONFIG_SYSLOG_MAX_CHANNELS] =
|
||||||
|
{
|
||||||
|
&g_default_channel
|
||||||
|
};
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Functions
|
* Private Functions
|
||||||
@ -135,14 +139,82 @@ static int syslog_default_putc(int ch)
|
|||||||
|
|
||||||
int syslog_channel(FAR const struct syslog_channel_s *channel)
|
int syslog_channel(FAR const struct syslog_channel_s *channel)
|
||||||
{
|
{
|
||||||
|
#if (CONFIG_SYSLOG_MAX_CHANNELS != 1)
|
||||||
|
int i;
|
||||||
|
#endif
|
||||||
|
|
||||||
DEBUGASSERT(channel != NULL);
|
DEBUGASSERT(channel != NULL);
|
||||||
|
|
||||||
if (channel != NULL)
|
if (channel != NULL)
|
||||||
{
|
{
|
||||||
DEBUGASSERT(channel->sc_putc != NULL && channel->sc_force != NULL);
|
DEBUGASSERT(channel->sc_putc != NULL && channel->sc_force != NULL);
|
||||||
|
|
||||||
g_syslog_channel = channel;
|
#if (CONFIG_SYSLOG_MAX_CHANNELS == 1)
|
||||||
|
g_syslog_channel[0] = channel;
|
||||||
return OK;
|
return OK;
|
||||||
|
#else
|
||||||
|
for (i = 0; i < CONFIG_SYSLOG_MAX_CHANNELS; i++)
|
||||||
|
{
|
||||||
|
if (g_syslog_channel[i] == NULL)
|
||||||
|
{
|
||||||
|
g_syslog_channel[i] = channel;
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
else if (g_syslog_channel[i] == channel)
|
||||||
|
{
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: syslog_channel_remove
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Removes an already configured SYSLOG channel from the list of used
|
||||||
|
* channels.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* channel - Provides the interface to the channel to be removed.
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* Zero (OK) is returned on success. A negated errno value is returned
|
||||||
|
* on any failure.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int syslog_channel_remove(FAR const struct syslog_channel_s *channel)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
DEBUGASSERT(channel != NULL);
|
||||||
|
|
||||||
|
if (channel != NULL)
|
||||||
|
{
|
||||||
|
for (i = 0; i < CONFIG_SYSLOG_MAX_CHANNELS; i++)
|
||||||
|
{
|
||||||
|
if (g_syslog_channel[i] == channel)
|
||||||
|
{
|
||||||
|
/* Get the rest of the channels one position back
|
||||||
|
* to ensure that there are no holes in the list.
|
||||||
|
*/
|
||||||
|
|
||||||
|
while (i < (CONFIG_SYSLOG_MAX_CHANNELS - 1) &&
|
||||||
|
g_syslog_channel[i + 1] != NULL)
|
||||||
|
{
|
||||||
|
g_syslog_channel[i] = g_syslog_channel[i + 1];
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_syslog_channel[i] = NULL;
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@ -64,21 +64,29 @@
|
|||||||
|
|
||||||
int syslog_flush(void)
|
int syslog_flush(void)
|
||||||
{
|
{
|
||||||
DEBUGASSERT(g_syslog_channel != NULL);
|
int i;
|
||||||
|
|
||||||
#ifdef CONFIG_SYSLOG_INTBUFFER
|
#ifdef CONFIG_SYSLOG_INTBUFFER
|
||||||
/* Flush any characters that may have been added to the interrupt
|
/* Flush any characters that may have been added to the interrupt
|
||||||
* buffer.
|
* buffer.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
syslog_flush_intbuffer(g_syslog_channel, true);
|
syslog_flush_intbuffer(true);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Then flush all of the buffered output to the SYSLOG device */
|
for (i = 0; i < CONFIG_SYSLOG_MAX_CHANNELS; i++)
|
||||||
|
|
||||||
if (g_syslog_channel->sc_flush != NULL)
|
|
||||||
{
|
{
|
||||||
return g_syslog_channel->sc_flush();
|
if (g_syslog_channel[i] == NULL)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Then flush all of the buffered output to the SYSLOG device */
|
||||||
|
|
||||||
|
if (g_syslog_channel[i]->sc_flush != NULL)
|
||||||
|
{
|
||||||
|
g_syslog_channel[i]->sc_flush();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
|
@ -55,18 +55,29 @@
|
|||||||
|
|
||||||
int syslog_force(int ch)
|
int syslog_force(int ch)
|
||||||
{
|
{
|
||||||
DEBUGASSERT(g_syslog_channel != NULL &&
|
int i;
|
||||||
g_syslog_channel->sc_force != NULL);
|
|
||||||
|
|
||||||
#ifdef CONFIG_SYSLOG_INTBUFFER
|
#ifdef CONFIG_SYSLOG_INTBUFFER
|
||||||
/* Flush any characters that may have been added to the interrupt
|
/* Flush any characters that may have been added to the interrupt
|
||||||
* buffer through the emergency channel
|
* buffer through the emergency channel
|
||||||
*/
|
*/
|
||||||
|
|
||||||
syslog_flush_intbuffer(g_syslog_channel, true);
|
syslog_flush_intbuffer(true);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Then send the character to the emergency channel */
|
for (i = 0; i < CONFIG_SYSLOG_MAX_CHANNELS; i++)
|
||||||
|
{
|
||||||
|
if (g_syslog_channel[i] == NULL)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
return g_syslog_channel->sc_force(ch);
|
DEBUGASSERT(g_syslog_channel[i]->sc_force != NULL);
|
||||||
|
|
||||||
|
/* Then send the character to the emergency channel */
|
||||||
|
|
||||||
|
g_syslog_channel[i]->sc_force(ch);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ch;
|
||||||
}
|
}
|
||||||
|
@ -264,7 +264,6 @@ int syslog_add_intbuffer(int ch)
|
|||||||
* to the SYSLOG device.
|
* to the SYSLOG device.
|
||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* channel - The syslog channel to use in performing the flush operation.
|
|
||||||
* force - Use the force() method of the channel vs. the putc() method.
|
* force - Use the force() method of the channel vs. the putc() method.
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* Returned Value:
|
||||||
@ -276,41 +275,49 @@ int syslog_add_intbuffer(int ch)
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
int syslog_flush_intbuffer(FAR const struct syslog_channel_s *channel,
|
int syslog_flush_intbuffer(bool force)
|
||||||
bool force)
|
|
||||||
{
|
{
|
||||||
syslog_putc_t putfunc;
|
syslog_putc_t putfunc;
|
||||||
int ch;
|
int ch;
|
||||||
int ret = OK;
|
int i;
|
||||||
|
|
||||||
/* Select which putc function to use for this flush */
|
|
||||||
|
|
||||||
putfunc = force ? channel->sc_putc : channel->sc_force;
|
|
||||||
|
|
||||||
/* This logic is performed with the scheduler disabled to protect from
|
/* This logic is performed with the scheduler disabled to protect from
|
||||||
* concurrent modification by other tasks.
|
* concurrent modification by other tasks.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
sched_lock();
|
sched_lock();
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
/* Transfer one character to time. This is inefficient, but is
|
/* Transfer one character to time. This is inefficient, but is
|
||||||
* done in this way to: (1) Deal with concurrent modification of
|
* done in this way to: (1) Deal with concurrent modification of
|
||||||
* the interrupt buffer from interrupt activity, (2) Avoid keeper
|
* the interrupt buffer from interrupt activity, (2) Avoid keeper
|
||||||
* interrupts disabled for a long time, and (3) to handler
|
* interrupts disabled for a long time, and (3) to handler
|
||||||
* wraparound of the circular buffer indices.
|
* wrap-around of the circular buffer indices.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ch = syslog_remove_intbuffer();
|
ch = syslog_remove_intbuffer();
|
||||||
if (ch != EOF)
|
|
||||||
|
for (i = 0; i < CONFIG_SYSLOG_MAX_CHANNELS; i++)
|
||||||
{
|
{
|
||||||
ret = putfunc(ch);
|
if ((g_syslog_channel[i] == NULL) || (ch == EOF))
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Select which putc function to use for this flush */
|
||||||
|
|
||||||
|
putfunc = force ? g_syslog_channel[i]->sc_putc :
|
||||||
|
g_syslog_channel[i]->sc_force;
|
||||||
|
|
||||||
|
putfunc(ch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while (ch != EOF && ret >= 0);
|
while (ch != EOF);
|
||||||
|
|
||||||
sched_unlock();
|
sched_unlock();
|
||||||
return ret;
|
|
||||||
|
return ch;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* CONFIG_SYSLOG_INTBUFFER */
|
#endif /* CONFIG_SYSLOG_INTBUFFER */
|
||||||
|
@ -55,7 +55,7 @@
|
|||||||
|
|
||||||
int syslog_putc(int ch)
|
int syslog_putc(int ch)
|
||||||
{
|
{
|
||||||
DEBUGASSERT(g_syslog_channel != NULL);
|
int i;
|
||||||
|
|
||||||
/* Is this an attempt to do SYSLOG output from an interrupt handler? */
|
/* Is this an attempt to do SYSLOG output from an interrupt handler? */
|
||||||
|
|
||||||
@ -65,8 +65,8 @@ int syslog_putc(int ch)
|
|||||||
if (up_interrupt_context())
|
if (up_interrupt_context())
|
||||||
{
|
{
|
||||||
/* Buffer the character in the interrupt buffer.
|
/* Buffer the character in the interrupt buffer.
|
||||||
* The interrupt buffer will be flushed before the next normal,
|
* The interrupt buffer will be flushed before the next
|
||||||
* non-interrupt SYSLOG output.
|
* normal,non-interrupt SYSLOG output.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
return syslog_add_intbuffer(ch);
|
return syslog_add_intbuffer(ch);
|
||||||
@ -76,27 +76,46 @@ int syslog_putc(int ch)
|
|||||||
{
|
{
|
||||||
/* Force the character to the SYSLOG device immediately
|
/* Force the character to the SYSLOG device immediately
|
||||||
* (if possible).
|
* (if possible).
|
||||||
* This means that the interrupt data may not be in synchronization
|
* This means that the interrupt data may not be in
|
||||||
* with output data that may have been buffered by sc_putc().
|
* synchronization with output data that may have been
|
||||||
|
* buffered by sc_putc().
|
||||||
*/
|
*/
|
||||||
|
|
||||||
DEBUGASSERT(g_syslog_channel->sc_force != NULL);
|
for (i = 0; i < CONFIG_SYSLOG_MAX_CHANNELS; i++)
|
||||||
|
{
|
||||||
|
if (g_syslog_channel[i] == NULL)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
return g_syslog_channel->sc_force(ch);
|
DEBUGASSERT(g_syslog_channel[i]->sc_force != NULL);
|
||||||
|
|
||||||
|
g_syslog_channel[i]->sc_force(ch);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DEBUGASSERT(g_syslog_channel->sc_putc != NULL);
|
|
||||||
|
|
||||||
#ifdef CONFIG_SYSLOG_INTBUFFER
|
#ifdef CONFIG_SYSLOG_INTBUFFER
|
||||||
/* Flush any characters that may have been added to the interrupt
|
/* Flush any characters that may have been added to the interrupt
|
||||||
* buffer.
|
* buffer.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
syslog_flush_intbuffer(g_syslog_channel, false);
|
syslog_flush_intbuffer(false);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return g_syslog_channel->sc_putc(ch);
|
for (i = 0; i < CONFIG_SYSLOG_MAX_CHANNELS; i++)
|
||||||
|
{
|
||||||
|
if (g_syslog_channel[i] == NULL)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUGASSERT(g_syslog_channel[i]->sc_putc != NULL);
|
||||||
|
|
||||||
|
g_syslog_channel[i]->sc_putc(ch);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return ch;
|
||||||
}
|
}
|
||||||
|
@ -56,7 +56,8 @@
|
|||||||
|
|
||||||
static ssize_t syslog_default_write(FAR const char *buffer, size_t buflen)
|
static ssize_t syslog_default_write(FAR const char *buffer, size_t buflen)
|
||||||
{
|
{
|
||||||
size_t nwritten;
|
int i;
|
||||||
|
size_t nwritten = 0;
|
||||||
|
|
||||||
if (up_interrupt_context() || sched_idletask())
|
if (up_interrupt_context() || sched_idletask())
|
||||||
{
|
{
|
||||||
@ -70,23 +71,43 @@ static ssize_t syslog_default_write(FAR const char *buffer, size_t buflen)
|
|||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
DEBUGASSERT(g_syslog_channel->sc_force != NULL);
|
for (i = 0; i < CONFIG_SYSLOG_MAX_CHANNELS; i++)
|
||||||
g_syslog_channel->sc_force(*buffer++);
|
{
|
||||||
|
if (g_syslog_channel[i] == NULL)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUGASSERT(g_syslog_channel[i]->sc_force != NULL);
|
||||||
|
g_syslog_channel[i]->sc_force(*buffer++);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef CONFIG_SYSLOG_WRITE
|
|
||||||
else if (g_syslog_channel->sc_write)
|
|
||||||
{
|
|
||||||
nwritten = g_syslog_channel->sc_write(buffer, buflen);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (nwritten = 0; nwritten < buflen; nwritten++)
|
for (i = 0; i < CONFIG_SYSLOG_MAX_CHANNELS; i++)
|
||||||
{
|
{
|
||||||
DEBUGASSERT(g_syslog_channel->sc_putc != NULL);
|
if (g_syslog_channel[i] == NULL)
|
||||||
g_syslog_channel->sc_putc(*buffer++);
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_SYSLOG_WRITE
|
||||||
|
if (g_syslog_channel[i]->sc_write)
|
||||||
|
{
|
||||||
|
nwritten = g_syslog_channel[i]->sc_write(buffer, buflen);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
DEBUGASSERT(g_syslog_channel[i]->sc_putc != NULL);
|
||||||
|
|
||||||
|
for (nwritten = 0; nwritten < buflen; nwritten++)
|
||||||
|
{
|
||||||
|
g_syslog_channel[i]->sc_putc(*buffer++);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -122,7 +143,7 @@ ssize_t syslog_write(FAR const char *buffer, size_t buflen)
|
|||||||
* buffer.
|
* buffer.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
syslog_flush_intbuffer(g_syslog_channel, false);
|
syslog_flush_intbuffer(false);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -131,13 +131,31 @@ extern "C"
|
|||||||
* channel - Provides the interface to the channel to be used.
|
* channel - Provides the interface to the channel to be used.
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* Returned Value:
|
||||||
* Zero (OK)is returned on success. A negated errno value is returned
|
* Zero (OK) is returned on success. A negated errno value is returned
|
||||||
* on any failure.
|
* on any failure.
|
||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
int syslog_channel(FAR const struct syslog_channel_s *channel);
|
int syslog_channel(FAR const struct syslog_channel_s *channel);
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: syslog_channel_remove
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Removes an already configured SYSLOG channel from the list of used
|
||||||
|
* channels.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* channel - Provides the interface to the channel to be removed.
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* Zero (OK) is returned on success. A negated errno value is returned
|
||||||
|
* on any failure.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int syslog_channel_remove(FAR const struct syslog_channel_s *channel);
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: syslog_initialize
|
* Name: syslog_initialize
|
||||||
*
|
*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user