summaryrefslogtreecommitdiffstats
path: root/runtime/statsobj.h
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/statsobj.h')
-rw-r--r--runtime/statsobj.h203
1 files changed, 203 insertions, 0 deletions
diff --git a/runtime/statsobj.h b/runtime/statsobj.h
new file mode 100644
index 0000000..d57cd0e
--- /dev/null
+++ b/runtime/statsobj.h
@@ -0,0 +1,203 @@
+/* The statsobj object.
+ *
+ * Copyright 2010-2016 Rainer Gerhards and Adiscon GmbH.
+ *
+ * This file is part of the rsyslog runtime library.
+ *
+ * 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
+ * -or-
+ * see COPYING.ASL20 in the source distribution
+ *
+ * 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 INCLUDED_STATSOBJ_H
+#define INCLUDED_STATSOBJ_H
+
+#include "atomic.h"
+
+/* The following data item is somewhat dirty, in that it does not follow
+ * our usual object calling conventions. However, much like with "Debug", we
+ * do this to gain speed. If we finally come to a platform that does not
+ * provide resolution of names for dynamically loaded modules, we need to find
+ * a work-around, but until then, we use the direct access.
+ * If set to 0, statistics are not gathered, otherwise they are.
+ */
+extern int GatherStats;
+
+/* our basic counter type -- need 32 bit on 32 bit platform.
+ * IMPORTANT: this type *MUST* be supported by atomic instructions!
+ */
+typedef uint64 intctr_t;
+
+/* counter types */
+typedef enum statsCtrType_e {
+ ctrType_IntCtr,
+ ctrType_Int
+} statsCtrType_t;
+
+/* stats line format types */
+typedef enum statsFmtType_e {
+ statsFmt_Legacy,
+ statsFmt_JSON,
+ statsFmt_JSON_ES,
+ statsFmt_CEE
+} statsFmtType_t;
+
+/* counter flags */
+#define CTR_FLAG_NONE 0
+#define CTR_FLAG_RESETTABLE 1
+#define CTR_FLAG_MUST_RESET 2
+
+/* statsobj flags */
+#define STATSOBJ_FLAG_NONE 0
+#define STATSOBJ_FLAG_DO_PREPEND 1
+
+/* helper entity, the counter */
+typedef struct ctr_s {
+ uchar *name;
+ statsCtrType_t ctrType;
+ union {
+ intctr_t *pIntCtr;
+ int *pInt;
+ } val;
+ int8_t flags;
+ struct ctr_s *next, *prev;
+} ctr_t;
+
+/* the statsobj object */
+struct statsobj_s {
+ BEGINobjInstance; /* Data to implement generic object - MUST be the first data element! */
+ uchar *name;
+ uchar *origin;
+ uchar *reporting_ns;
+ statsobj_read_notifier_t read_notifier;
+ void *read_notifier_ctx;
+ pthread_mutex_t mutCtr; /* to guard counter linked-list ops */
+ ctr_t *ctrRoot; /* doubly-linked list of statsobj counters */
+ ctr_t *ctrLast;
+ int flags;
+ /* used to link ourselves together */
+ statsobj_t *prev;
+ statsobj_t *next;
+};
+
+struct sender_stats {
+ const uchar *sender;
+ uint64_t nMsgs;
+ time_t lastSeen;
+};
+
+
+/* interfaces */
+BEGINinterface(statsobj) /* name must also be changed in ENDinterface macro! */
+ INTERFACEObjDebugPrint(statsobj);
+ rsRetVal (*Construct)(statsobj_t **ppThis);
+ rsRetVal (*ConstructFinalize)(statsobj_t *pThis);
+ rsRetVal (*Destruct)(statsobj_t **ppThis);
+ rsRetVal (*SetName)(statsobj_t *pThis, uchar *name);
+ rsRetVal (*SetOrigin)(statsobj_t *pThis, uchar *name); /* added v12, 2014-09-08 */
+ rsRetVal (*SetReadNotifier)(statsobj_t *pThis, statsobj_read_notifier_t notifier, void* ctx);
+ rsRetVal (*SetReportingNamespace)(statsobj_t *pThis, uchar *ns);
+ void (*SetStatsObjFlags)(statsobj_t *pThis, int flags);
+ rsRetVal (*GetAllStatsLines)(rsRetVal(*cb)(void*, const char*), void *usrptr, statsFmtType_t fmt,
+ int8_t bResetCtr);
+ rsRetVal (*AddCounter)(statsobj_t *pThis, const uchar *ctrName, statsCtrType_t ctrType, int8_t flags,
+ void *pCtr);
+ rsRetVal (*AddManagedCounter)(statsobj_t *pThis, const uchar *ctrName, statsCtrType_t ctrType, int8_t flags,
+ void *pCtr, ctr_t **ref, int8_t linked);
+ void (*AddPreCreatedCtr)(statsobj_t *pThis, ctr_t *ctr);
+ void (*DestructCounter)(statsobj_t *pThis, ctr_t *ref);
+ void (*DestructUnlinkedCounter)(ctr_t *ctr);
+ ctr_t* (*UnlinkAllCounters)(statsobj_t *pThis);
+ rsRetVal (*EnableStats)(void);
+ENDinterface(statsobj)
+#define statsobjCURR_IF_VERSION 13 /* increment whenever you change the interface structure! */
+/* Changes
+ * v2-v9 rserved for future use in "older" version branches
+ * v10, 2012-04-01: GetAllStatsLines got fmt parameter
+ * v11, 2013-09-07: - add "flags" to AddCounter API
+ * - GetAllStatsLines got parameter telling if ctrs shall be reset
+ * v13, 2016-05-19: GetAllStatsLines cb data type changed (char* instead of cstr)
+ */
+
+
+/* prototypes */
+PROTOTYPEObj(statsobj);
+
+rsRetVal statsRecordSender(const uchar *sender, unsigned nMsgs, time_t lastSeen);
+/* checkGoneAwaySenders() is part of this module because all it needs is
+ * done by this module, so even though it's own processing is not directly
+ * related to stats, it makes sense to do it here... -- rgerhards, 2016-02-01
+ */
+void checkGoneAwaySenders(time_t);
+
+/* macros to handle stats counters
+ * These are to be used by "counter providers". Note that we MUST
+ * specify the mutex name, even though at first it looks like it
+ * could be automatically be generated via e.g. "mut##ctr".
+ * Unfortunately, this does not work if counter is e.g. "pThis->ctr".
+ * So we decided, for clarity, to always insist on specifying the mutex
+ * name (after all, it's just a few more keystrokes...).
+ * --------------------------------------------------------------------
+ * NOTE WELL
+ * --------------------------------------------------------------------
+ * There are actually two types of stats counters: "regular" counters,
+ * which are only used for stats purposes and "dual" counters, which
+ * are primarily used for other purposes but can be included in stats
+ * as well. ALL regular counters MUST be initialized with
+ * STATSCOUNTER_INIT and only be modified by STATSCOUNTER_* functions.
+ * They MUST NOT be used for any other purpose (if this seems to make
+ * sense, consider changing it to a dual counter).
+ * Dual counters are somewhat dangerous in that a single variable is
+ * used for two purposes: the actual application need and stats
+ * counting. However, this is supported for performance reasons, as it
+ * provides insight into the inner engine workings without need for
+ * additional counters (and their maintenance code). Dual counters
+ * MUST NOT be modified by STATSCOUNTER_* functions. Most importantly,
+ * it is expected that the actua application code provides proper
+ * (enough) synchronized access to these counters. Most importantly,
+ * this means they have NO stats-system mutex associated to them.
+ *
+ * The interface function AddCounter() is a read-only function. It
+ * only provides the stats subsystem with a reference to a counter.
+ * It is irrelevant if the counter is a regular or dual one. For that
+ * reason, AddCounter() must not modify the counter contents, as in
+ * the case of a dual counter application code may be broken.
+ */
+#define STATSCOUNTER_DEF(ctr, mut) \
+ intctr_t ctr; \
+ DEF_ATOMIC_HELPER_MUT64(mut)
+
+#define STATSCOUNTER_INIT(ctr, mut) \
+ INIT_ATOMIC_HELPER_MUT64(mut); \
+ ctr = 0;
+
+#define STATSCOUNTER_INC(ctr, mut) \
+ if(GatherStats) \
+ ATOMIC_INC_uint64(&ctr, &mut);
+
+#define STATSCOUNTER_ADD(ctr, mut, delta) \
+ if(GatherStats) \
+ ATOMIC_ADD_uint64(&ctr, &mut, delta);
+
+#define STATSCOUNTER_DEC(ctr, mut) \
+ if(GatherStats) \
+ ATOMIC_DEC_uint64(&ctr, &mut);
+
+/* the next macro works only if the variable is already guarded
+ * by mutex (or the users risks a wrong result). It is assumed
+ * that there are not concurrent operations that modify the counter.
+ */
+#define STATSCOUNTER_SETMAX_NOMUT(ctr, newmax) \
+ if(GatherStats && ((newmax) > (ctr))) \
+ ctr = newmax;
+
+#endif /* #ifndef INCLUDED_STATSOBJ_H */