syslog-ng source
stats-compat.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2023 László Várady
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17  *
18  * As an additional exemption you are allowed to compile & link against the
19  * OpenSSL libraries as published by the OpenSSL project. See the file
20  * COPYING for details.
21  *
22  */
23 #ifndef STATS_COMPAT_H
24 #define STATS_COMPAT_H
25 
26 #include "syslog-ng.h"
27 #include "stats-counter.h"
28 #include "stats-cluster.h"
29 #include "stats-cluster-single.h"
30 #include "stats-registry.h"
31 #include "atomic-gssize.h"
32 
33 #include <stdint.h>
34 
35 /*
36  * StatsByteCounter allows representing "big" accumulating byte-based metrics
37  * even on 32-bit architectures, where a simple stats-counter would overflow
38  * after 4 GiB.
39  *
40  * When 64-bit counters are available, they will be used.
41  * If not, the counters lose precision but are able to represent larger values.
42  *
43  * The current implementation is not thread-safe, reimplement it using a CAS
44  * loop when needed.
45  */
46 
47 typedef enum _StatsByteCounterPrecision
48 {
53 
54 typedef struct _StatsByteCounter
55 {
57 
58 #if STATS_COUNTER_MAX_VALUE < UINT64_MAX
59  atomic_gssize counter_cache;
60  gsize precision;
61 #endif
63 
64 static inline void
65 stats_byte_counter_init(StatsByteCounter *self, StatsClusterKey *key, gint stats_level,
66  StatsByteCounterPrecision min_precision)
67 {
68  *self = (StatsByteCounter)
69  {
70  0
71  };
72 
73 #if STATS_COUNTER_MAX_VALUE < UINT64_MAX
75 
76  switch (min_precision)
77  {
78  case SBCP_KIB:
79  self->precision = 1024;
80  unit = SCU_KIB;
81  break;
82  case SBCP_MIB:
83  self->precision = 1024 * 1024;
84  unit = SCU_MIB;
85  break;
86  case SBCP_GIB:
87  self->precision = 1024 * 1024 * 1024;
88  unit = SCU_GIB;
89  break;
90  default:
91  g_assert_not_reached();
92  }
93 
95 #endif
96 
97  stats_lock();
98  stats_register_counter(stats_level, key, SC_TYPE_SINGLE_VALUE, &self->counter);
99  stats_unlock();
100 }
101 
102 static inline void
103 stats_byte_counter_deinit(StatsByteCounter *self, StatsClusterKey *key)
104 {
105  stats_lock();
107  stats_unlock();
108 }
109 
110 /* this is currently NOT thread-safe */
111 static inline void
112 stats_byte_counter_add(StatsByteCounter *self, gsize add)
113 {
114 #if STATS_COUNTER_MAX_VALUE < UINT64_MAX
115  if (!self->counter)
116  return;
117 
118  self->counter_cache.value += add;
119 
120  if (self->counter_cache.value > (gssize) self->precision)
121  {
122  stats_counter_add(self->counter, self->counter_cache.value / self->precision);
123  self->counter_cache.value %= self->precision;
124  }
125 #else
126  stats_counter_add(self->counter, add);
127 #endif
128 }
129 
130 #endif
#define self
Definition: rcptid.c:38
void stats_cluster_single_key_add_unit(StatsClusterKey *key, StatsClusterUnit stored_unit)
Definition: stats-cluster-single.c:151
@ SC_TYPE_SINGLE_VALUE
Definition: stats-cluster-single.h:33
StatsClusterUnit
Definition: stats-cluster.h:50
@ SCU_KIB
Definition: stats-cluster.h:60
@ SCU_BYTES
Definition: stats-cluster.h:59
@ SCU_MIB
Definition: stats-cluster.h:61
@ SCU_GIB
Definition: stats-cluster.h:62
StatsByteCounterPrecision
Definition: stats-compat.h:48
@ SBCP_GIB
Definition: stats-compat.h:51
@ SBCP_KIB
Definition: stats-compat.h:49
@ SBCP_MIB
Definition: stats-compat.h:50
void stats_unlock(void)
Definition: stats-registry.c:63
StatsCluster * stats_register_counter(gint stats_level, const StatsClusterKey *sc_key, gint type, StatsCounterItem **counter)
Definition: stats-registry.c:225
void stats_lock(void)
Definition: stats-registry.c:56
void stats_unregister_counter(const StatsClusterKey *sc_key, gint type, StatsCounterItem **counter)
Definition: stats-registry.c:302
Definition: stats-compat.h:55
StatsCounterItem * counter
Definition: stats-compat.h:56
Definition: stats-counter.h:67
Definition: atomic-gssize.h:33
struct tm key
Definition: cache.c:63