Skip to content
Merged
26 changes: 20 additions & 6 deletions caPutLogApp/caPutJsonLogTask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ caPutJsonLogStatus CaPutJsonLogTask::report(int level)
for (client = clients; client; client = client->next) {
logClientShow(client->caPutJsonLogClient, level);
}
printf("caPutJsonLog: Total count = %d\n", epics::atomic::get(this->caPutTotalCount));
return caPutJsonLogSuccess;
}
else {
Expand Down Expand Up @@ -272,11 +273,14 @@ caPutJsonLogStatus CaPutJsonLogTask::configurePvLogging()
void CaPutJsonLogTask::caPutJsonLogTask(void *arg)
{

bool sent = false, burst = false;
bool sent = false;
int burst = 0;
LOGDATA *pcurrent, *pnext;
VALUE old_value, max_value, min_value;
VALUE *pold=&old_value, *pmax=&max_value, *pmin=&min_value;

epics::atomic::set(this->caPutTotalCount, 0);

// Receive 1st message
this->caPutJsonLogQ.receive(&pcurrent, sizeof(LOGDATA *));
std::memcpy(pold, &pcurrent->old_value, sizeof(VALUE));
Expand All @@ -301,7 +305,7 @@ void CaPutJsonLogTask::caPutJsonLogTask(void *arg)
buildJsonMsg(pold, pcurrent, burst, pmin, pmax);
std::memcpy(pold, &pcurrent->new_value.value, sizeof(VALUE));
sent = true;
burst = false;
burst = 0;
}
}

Expand All @@ -319,19 +323,21 @@ void CaPutJsonLogTask::caPutJsonLogTask(void *arg)
caPutLogDataFree(pcurrent);
pcurrent = pnext;

epics::atomic::increment(this->caPutTotalCount);

// First message after logging
if (sent) {
// Set new initial max & min values
std::memcpy(pmax, &pcurrent->new_value.value, sizeof(VALUE));
std::memcpy(pmin, &pcurrent->new_value.value, sizeof(VALUE));

sent = false;
burst = false;
burst = 0;
}
// Multiple puts within timeout
else {
if (isDbrNumeric(pcurrent->type) && pcurrent->new_size == 1) {
burst = true;
burst++;
calculateMax(pmax, &pcurrent->new_value.value, pmax, pcurrent->type);
calculateMin(pmin, &pcurrent->new_value.value, pmin, pcurrent->type);
}
Expand All @@ -348,6 +354,8 @@ void CaPutJsonLogTask::caPutJsonLogTask(void *arg)
caPutLogDataFree(pcurrent);
pcurrent = pnext;

epics::atomic::increment(this->caPutTotalCount);

/* Set new old_value */
std::memcpy(pold, &pcurrent->old_value, sizeof(VALUE));

Expand All @@ -356,7 +364,7 @@ void CaPutJsonLogTask::caPutJsonLogTask(void *arg)
std::memcpy(pmin, &pcurrent->new_value.value, sizeof(VALUE));

sent = false;
burst = false;
burst = 0;
}
}
epics::atomic::set(this->taskStopper, false);
Expand All @@ -383,7 +391,7 @@ void CaPutJsonLogTask::addPutToQueue(LOGDATA * plogData)
}

caPutJsonLogStatus CaPutJsonLogTask::buildJsonMsg(const VALUE *pold_value, const LOGDATA *pLogData,
bool burst, const VALUE *pmin, const VALUE *pmax)
int burst, const VALUE *pmin, const VALUE *pmax)
{
// Intermediate message build buffer
// The longest message for the buffer can occur in the lso/lsi records which
Expand Down Expand Up @@ -583,6 +591,12 @@ caPutJsonLogStatus CaPutJsonLogTask::buildJsonMsg(const VALUE *pold_value, const
CALL_YAJL_FUNCTION_AND_CHECK_STATUS(status, yajl_gen_number(handle,
reinterpret_cast<const char *>(interBuffer),
strlen(reinterpret_cast<char *>(interBuffer))));

// Add burst count
const unsigned char str_burst[] = "burst";
CALL_YAJL_FUNCTION_AND_CHECK_STATUS(status, yajl_gen_string(handle, str_burst,
strlen(reinterpret_cast<const char *>(str_burst))));
CALL_YAJL_FUNCTION_AND_CHECK_STATUS(status, yajl_gen_integer(handle, burst));
}

/* Close root map */
Expand Down
10 changes: 6 additions & 4 deletions caPutLogApp/caPutJsonLogTask.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ enum specialValues {
* \code{.txt}
* <iocLogPrefix>{"date": "<dd>-<mm>-<yyyy>"","time":"<hh>:<mm>:<ss>","host":"<client hostname>","user":"<client username>","pv":"<pv name>","new":<new value>,"old":"<old value>"}\n
* \endcode
* Burst puts add extra JSON properties (supported only for numberic scalar puts):
* Burst puts add extra JSON properties (supported only for numeric scalar puts):
* - "min": Which is a minimum value inside the burst period
* - "max": Represents maximum value inside the burst of puts
* Array puts add following JSON properties:
Expand Down Expand Up @@ -144,7 +144,7 @@ class epicsShareClass CaPutJsonLogTask {

private:

// Singelton instance of this class.
// Singleton instance of this class.
static CaPutJsonLogTask *instance;

// Logger configuration
Expand All @@ -169,6 +169,8 @@ class epicsShareClass CaPutJsonLogTask {
DBADDR caPutJsonLogPV;
DBADDR *pCaPutJsonLogPV;

// Total count of logged puts
int caPutTotalCount; // To modify or read this value only epicsAtomic methods should be used

// Class methods (Do not allow public constructors - class is designed as singleton)
CaPutJsonLogTask();
Expand All @@ -183,13 +185,13 @@ class epicsShareClass CaPutJsonLogTask {
*
* @param pold_value Pointer to a ::VALUE structure holding an old PV value.
* @param pLogData Pointer to a ::LOGDATA structure holding new value and other meta databa about the put.
* @param burst Boolean value. It determinate if put was a burst of values.
* @param burst Integer value. Indicates the number of burst of values, if any.
* @param pmin Pointer to a ::VALUE structure holding an min value if burst is true.
* @param pmax Pointer to a ::VALUE structure holding an max value if burst is true.
* @return int Status code.
*/
caPutJsonLogStatus buildJsonMsg(const VALUE *pold_value, const LOGDATA *pLogData,
bool burst, const VALUE *pmin, const VALUE *pmax);
int burst, const VALUE *pmin, const VALUE *pmax);

/**
* @brief Configure logging to a server.
Expand Down
25 changes: 19 additions & 6 deletions caPutLogApp/caPutLogTask.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
#include <errlog.h>
#include <asLib.h>
#include <epicsAssert.h>
#include <epicsAtomic.h>

#include <epicsExport.h>
#include "caPutLog.h"
Expand Down Expand Up @@ -112,6 +113,8 @@ static volatile int caPutLogConfig;
int caPutLogDebug = 0;
epicsExportAddress(int, caPutLogDebug);

int caPutLogTotalCount = 0;

#define MAX_MSGS 1000 /* The length of queue (in messages) */
#define MSG_SIZE sizeof(LOGDATA*) /* We store only pointers */

Expand Down Expand Up @@ -184,6 +187,7 @@ void caPutLogTaskShow(void)
default: state = "invalid";
}
printf("caPutLog mode: %d = %s\n", caPutLogConfig, state);
printf("caPutLog Total Count: %d\n", epicsAtomicGetIntT(&caPutLogTotalCount));
}

void caPutLogTaskStop(void)
Expand Down Expand Up @@ -220,9 +224,11 @@ void caPutLogSetTimeFmt (const char *format)

static void caPutLogTask(void *arg)
{
int sent = FALSE, burst = FALSE;
int sent = FALSE;
int burst = 0;
int config;
int msg_size;

LOGDATA *pcurrent, *pnext;
VALUE old_value, max_value, min_value;
VALUE *pold=&old_value, *pmax=&max_value, *pmin=&min_value;
Expand Down Expand Up @@ -257,7 +263,7 @@ static void caPutLogTask(void *arg)
log_msg(pold, pcurrent, burst, pmin, pmax, config);
val_assign(pold, &pcurrent->new_value.value, pcurrent->type);
sent = TRUE;
burst = FALSE;
burst = 0;
}
}
else if (msg_size != MSG_SIZE) {
Expand All @@ -270,21 +276,22 @@ static void caPutLogTask(void *arg)
}

/* current and next are same pv */

caPutLogDataFree(pcurrent);
pcurrent = pnext;

epicsAtomicIncrIntT(&caPutLogTotalCount);

if (sent) {
/* Set new initial max & min values */
val_assign(pmax, &pcurrent->new_value.value, pcurrent->type);
val_assign(pmin, &pcurrent->new_value.value, pcurrent->type);

sent = FALSE;
burst = FALSE; /* First message after logging */
burst = 0; /* First message after logging */
}
else { /* Next put of multiple puts */
if (isDbrNumeric(pcurrent->type)) {
burst = TRUE;
burst++;
val_max(pmax, &pcurrent->new_value.value, pmax, pcurrent->type);
val_min(pmin, &pcurrent->new_value.value, pmin, pcurrent->type);
}
Expand All @@ -305,6 +312,8 @@ static void caPutLogTask(void *arg)
caPutLogDataFree(pcurrent);
pcurrent = pnext;

epicsAtomicIncrIntT(&caPutLogTotalCount);

/* Set new old_value */
val_assign(pold, &pcurrent->old_value, pcurrent->type);

Expand All @@ -313,7 +322,7 @@ static void caPutLogTask(void *arg)
val_assign(pmin, &pcurrent->new_value.value, pcurrent->type);

sent = FALSE;
burst = FALSE;
burst = 0;
}
}
errlogSevPrintf(errlogInfo, "caPutLog: log task exiting\n");
Expand Down Expand Up @@ -397,6 +406,10 @@ static void log_msg(const VALUE *pold_value, const LOGDATA *pLogData,
if (len >= space) { do_log(msg, space-1, YES); return; }
len += val_to_string(msg+len, space-len, pmax, pLogData->type);
if (len >= space) { do_log(msg, space-1, YES); return; }

/* burst count */
len += epicsSnprintf(msg+len, space-len, " burst=%d", burst);
if (len >= space) { do_log(msg, space-1, YES); return; }
}
do_log(msg, len, NO);
}
Expand Down
19 changes: 12 additions & 7 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,8 @@ Other shell commands for controlling the logger are:
``caPutLogShow level`` / ``caPutJsonLogShow level``

Show information about an active logger, including its current ``config``
setting. ``level`` is the usual interest level (0, 1, or 2).
setting and total number of logged puts. ``level`` is the usual interest
level (0, 1, or 2).


Set up a Log Server
Expand Down Expand Up @@ -201,12 +202,13 @@ record.field name, and <change> is either::

or::

new=<value> old=<value> min=<value> max=<value>
new=<value> old=<value> min=<value> max=<value> burst=<value>

The latter format means that several puts for the same PV were received in quick
succession; in this case only the original and final values of the burst as well
as the minimum and maximum values seen are logged. This burst filtering can be
disabled by selecting the ``caPutLogAllNoFilter`` (``2``) configuration value.
as the minimum and maximum values seen are logged. The number of successive puts
filtered is also logged. This burst filtering can be disabled by selecting the
``caPutLogAllNoFilter`` (``2``) configuration value.

From release 4.0 on, string values are placed inside quotes, and special
characters within the string are escaped. The default date/time format
Expand All @@ -227,7 +229,8 @@ It looks like this::
"pv":"<pv name>",
"new":<new value>,["new-size":<new array size>,]
"old":<new value>[,"old-size":<old array size>]
[,"min":<minimum value>][,"max":<maximum value>]}<LF>
[,"min":<minimum value>][,"max":<maximum value>]
[,"burst":<burst count>]}<LF>

The JSON properties are:

Expand Down Expand Up @@ -266,6 +269,8 @@ The JSON properties are:
* **max** value is included only if the burst filtering was applied and
gives the maximum value of the puts received within the burst period.

* **burst** number of filtered puts in the burst period.

The JSON implementation of the logger added support for arrays and long string
fields. As these values can get very large, there is a limit to how long the
**new value** and **old value** properties can be. Each value can use up to 400
Expand Down Expand Up @@ -297,7 +302,8 @@ Burst of scalar values::
"host":"devWs","user":"devman",
"pv":"ao",
"new":8,"old":77.5,
"min":7.5,"max":870.5}<LF>
"min":7.5,"max":870.5,
"burst"=10}<LF>

String value::

Expand Down Expand Up @@ -400,4 +406,3 @@ If you have any problems with this module, send me (`Ben Franksen`_) a mail.
.. _R3-3: releasenotes.rst#r3-3-changes-since-r3-2
.. _R3-2: releasenotes.rst#r3-2-changes-since-r3-1
.. _R3-1: releasenotes.rst#r3-1-changes-since-r3-0