diff --git a/caPutLogApp/caPutJsonLogTask.cpp b/caPutLogApp/caPutJsonLogTask.cpp index a9c20c8..da15ac2 100644 --- a/caPutLogApp/caPutJsonLogTask.cpp +++ b/caPutLogApp/caPutJsonLogTask.cpp @@ -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 { @@ -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)); @@ -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; } } @@ -319,6 +323,8 @@ 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 @@ -326,12 +332,12 @@ void CaPutJsonLogTask::caPutJsonLogTask(void *arg) 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); } @@ -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)); @@ -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); @@ -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 @@ -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(interBuffer), strlen(reinterpret_cast(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(str_burst)))); + CALL_YAJL_FUNCTION_AND_CHECK_STATUS(status, yajl_gen_integer(handle, burst)); } /* Close root map */ diff --git a/caPutLogApp/caPutJsonLogTask.h b/caPutLogApp/caPutJsonLogTask.h index 3df4889..67a7832 100644 --- a/caPutLogApp/caPutJsonLogTask.h +++ b/caPutLogApp/caPutJsonLogTask.h @@ -55,7 +55,7 @@ enum specialValues { * \code{.txt} * {"date": "
--"","time":"::","host":"","user":"","pv":"","new":,"old":""}\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: @@ -144,7 +144,7 @@ class epicsShareClass CaPutJsonLogTask { private: - // Singelton instance of this class. + // Singleton instance of this class. static CaPutJsonLogTask *instance; // Logger configuration @@ -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(); @@ -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. diff --git a/caPutLogApp/caPutLogTask.c b/caPutLogApp/caPutLogTask.c index 51a81d9..e57c9f2 100644 --- a/caPutLogApp/caPutLogTask.c +++ b/caPutLogApp/caPutLogTask.c @@ -55,6 +55,7 @@ #include #include #include +#include #include #include "caPutLog.h" @@ -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 */ @@ -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) @@ -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; @@ -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) { @@ -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); } @@ -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); @@ -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"); @@ -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); } diff --git a/docs/index.rst b/docs/index.rst index 268640b..4b60923 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -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 @@ -201,12 +202,13 @@ record.field name, and is either:: or:: - new= old= min= max= + new= old= min= max= burst= 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 @@ -227,7 +229,8 @@ It looks like this:: "pv":"", "new":,["new-size":,] "old":[,"old-size":] - [,"min":][,"max":]} + [,"min":][,"max":] + [,"burst":]} The JSON properties are: @@ -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 @@ -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} + "min":7.5,"max":870.5, + "burst"=10} String value:: @@ -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 -