Added support for multiple syslog channels.
This commit is contained in:
parent
dc31b4f1c1
commit
f13adbe4bb
@ -17,6 +17,12 @@ config SYSLOG_WRITE
|
||||
bool
|
||||
default n
|
||||
|
||||
config SYSLOG_MAX_CHANNELS
|
||||
int "Maximum SYSLOG channels"
|
||||
default 1
|
||||
---help---
|
||||
Maximum number of supported SYSLOG channels.
|
||||
|
||||
config RAMLOG
|
||||
bool "RAM log device support"
|
||||
default n
|
||||
|
@ -48,7 +48,8 @@ extern "C"
|
||||
*/
|
||||
|
||||
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
|
||||
@ -216,7 +217,6 @@ int syslog_add_intbuffer(int ch);
|
||||
* to the SYSLOG device.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Returned Value:
|
||||
@ -229,8 +229,7 @@ int syslog_add_intbuffer(int ch);
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_SYSLOG_INTBUFFER
|
||||
int syslog_flush_intbuffer(FAR const struct syslog_channel_s *channel,
|
||||
bool force);
|
||||
int syslog_flush_intbuffer(bool force);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -92,7 +92,11 @@ static const struct syslog_channel_s g_default_channel =
|
||||
|
||||
/* 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
|
||||
@ -135,14 +139,82 @@ static int syslog_default_putc(int ch)
|
||||
|
||||
int syslog_channel(FAR const struct syslog_channel_s *channel)
|
||||
{
|
||||
#if (CONFIG_SYSLOG_MAX_CHANNELS != 1)
|
||||
int i;
|
||||
#endif
|
||||
|
||||
DEBUGASSERT(channel != NULL);
|
||||
|
||||
if (channel != 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;
|
||||
#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;
|
||||
|
@ -64,21 +64,29 @@
|
||||
|
||||
int syslog_flush(void)
|
||||
{
|
||||
DEBUGASSERT(g_syslog_channel != NULL);
|
||||
int i;
|
||||
|
||||
#ifdef CONFIG_SYSLOG_INTBUFFER
|
||||
/* Flush any characters that may have been added to the interrupt
|
||||
* buffer.
|
||||
*/
|
||||
|
||||
syslog_flush_intbuffer(g_syslog_channel, true);
|
||||
syslog_flush_intbuffer(true);
|
||||
#endif
|
||||
|
||||
for (i = 0; i < CONFIG_SYSLOG_MAX_CHANNELS; i++)
|
||||
{
|
||||
if (g_syslog_channel[i] == NULL)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
/* Then flush all of the buffered output to the SYSLOG device */
|
||||
|
||||
if (g_syslog_channel->sc_flush != NULL)
|
||||
if (g_syslog_channel[i]->sc_flush != NULL)
|
||||
{
|
||||
return g_syslog_channel->sc_flush();
|
||||
g_syslog_channel[i]->sc_flush();
|
||||
}
|
||||
}
|
||||
|
||||
return OK;
|
||||
|
@ -55,18 +55,29 @@
|
||||
|
||||
int syslog_force(int ch)
|
||||
{
|
||||
DEBUGASSERT(g_syslog_channel != NULL &&
|
||||
g_syslog_channel->sc_force != NULL);
|
||||
int i;
|
||||
|
||||
#ifdef CONFIG_SYSLOG_INTBUFFER
|
||||
/* Flush any characters that may have been added to the interrupt
|
||||
* buffer through the emergency channel
|
||||
*/
|
||||
|
||||
syslog_flush_intbuffer(g_syslog_channel, true);
|
||||
syslog_flush_intbuffer(true);
|
||||
#endif
|
||||
|
||||
for (i = 0; i < CONFIG_SYSLOG_MAX_CHANNELS; i++)
|
||||
{
|
||||
if (g_syslog_channel[i] == NULL)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
DEBUGASSERT(g_syslog_channel[i]->sc_force != NULL);
|
||||
|
||||
/* Then send the character to the emergency channel */
|
||||
|
||||
return g_syslog_channel->sc_force(ch);
|
||||
g_syslog_channel[i]->sc_force(ch);
|
||||
}
|
||||
|
||||
return ch;
|
||||
}
|
||||
|
@ -264,7 +264,6 @@ int syslog_add_intbuffer(int ch)
|
||||
* to the SYSLOG device.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Returned Value:
|
||||
@ -276,41 +275,49 @@ int syslog_add_intbuffer(int ch)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int syslog_flush_intbuffer(FAR const struct syslog_channel_s *channel,
|
||||
bool force)
|
||||
int syslog_flush_intbuffer(bool force)
|
||||
{
|
||||
syslog_putc_t putfunc;
|
||||
int ch;
|
||||
int ret = OK;
|
||||
|
||||
/* Select which putc function to use for this flush */
|
||||
|
||||
putfunc = force ? channel->sc_putc : channel->sc_force;
|
||||
int i;
|
||||
|
||||
/* This logic is performed with the scheduler disabled to protect from
|
||||
* concurrent modification by other tasks.
|
||||
*/
|
||||
|
||||
sched_lock();
|
||||
|
||||
do
|
||||
{
|
||||
/* Transfer one character to time. This is inefficient, but is
|
||||
* done in this way to: (1) Deal with concurrent modification of
|
||||
* the interrupt buffer from interrupt activity, (2) Avoid keeper
|
||||
* 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();
|
||||
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();
|
||||
return ret;
|
||||
|
||||
return ch;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_SYSLOG_INTBUFFER */
|
||||
|
@ -55,7 +55,7 @@
|
||||
|
||||
int syslog_putc(int ch)
|
||||
{
|
||||
DEBUGASSERT(g_syslog_channel != NULL);
|
||||
int i;
|
||||
|
||||
/* 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())
|
||||
{
|
||||
/* Buffer the character in the interrupt buffer.
|
||||
* The interrupt buffer will be flushed before the next normal,
|
||||
* non-interrupt SYSLOG output.
|
||||
* The interrupt buffer will be flushed before the next
|
||||
* normal,non-interrupt SYSLOG output.
|
||||
*/
|
||||
|
||||
return syslog_add_intbuffer(ch);
|
||||
@ -76,27 +76,46 @@ int syslog_putc(int ch)
|
||||
{
|
||||
/* Force the character to the SYSLOG device immediately
|
||||
* (if possible).
|
||||
* This means that the interrupt data may not be in synchronization
|
||||
* with output data that may have been buffered by sc_putc().
|
||||
* This means that the interrupt data may not be in
|
||||
* 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
|
||||
{
|
||||
DEBUGASSERT(g_syslog_channel->sc_putc != NULL);
|
||||
|
||||
#ifdef CONFIG_SYSLOG_INTBUFFER
|
||||
/* Flush any characters that may have been added to the interrupt
|
||||
* buffer.
|
||||
*/
|
||||
|
||||
syslog_flush_intbuffer(g_syslog_channel, false);
|
||||
syslog_flush_intbuffer(false);
|
||||
#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)
|
||||
{
|
||||
size_t nwritten;
|
||||
int i;
|
||||
size_t nwritten = 0;
|
||||
|
||||
if (up_interrupt_context() || sched_idletask())
|
||||
{
|
||||
@ -70,23 +71,43 @@ static ssize_t syslog_default_write(FAR const char *buffer, size_t buflen)
|
||||
else
|
||||
#endif
|
||||
{
|
||||
DEBUGASSERT(g_syslog_channel->sc_force != NULL);
|
||||
g_syslog_channel->sc_force(*buffer++);
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef CONFIG_SYSLOG_WRITE
|
||||
else if (g_syslog_channel->sc_write)
|
||||
for (i = 0; i < CONFIG_SYSLOG_MAX_CHANNELS; i++)
|
||||
{
|
||||
nwritten = g_syslog_channel->sc_write(buffer, buflen);
|
||||
if (g_syslog_channel[i] == NULL)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
DEBUGASSERT(g_syslog_channel[i]->sc_force != NULL);
|
||||
g_syslog_channel[i]->sc_force(*buffer++);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
for (i = 0; i < CONFIG_SYSLOG_MAX_CHANNELS; i++)
|
||||
{
|
||||
if (g_syslog_channel[i] == NULL)
|
||||
{
|
||||
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++)
|
||||
{
|
||||
DEBUGASSERT(g_syslog_channel->sc_putc != NULL);
|
||||
g_syslog_channel->sc_putc(*buffer++);
|
||||
g_syslog_channel[i]->sc_putc(*buffer++);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -122,7 +143,7 @@ ssize_t syslog_write(FAR const char *buffer, size_t buflen)
|
||||
* buffer.
|
||||
*/
|
||||
|
||||
syslog_flush_intbuffer(g_syslog_channel, false);
|
||||
syslog_flush_intbuffer(false);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -131,13 +131,31 @@ extern "C"
|
||||
* channel - Provides the interface to the channel to be used.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
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
|
||||
*
|
||||
|
Loading…
Reference in New Issue
Block a user