diameter: Support updating app with private metrics

This commit is contained in:
Pau Espin Pedrol 2024-09-02 20:18:40 +02:00 committed by Sukchan Lee
parent 902a602a2b
commit a37a2099fc
3 changed files with 42 additions and 0 deletions

View file

@ -32,6 +32,9 @@ extern "C" {
typedef struct ogs_diam_config_stats_s {
/* Frequency at which freeDiameter thread stats are updated to the app. 0 = default 60 seconds. */
unsigned int interval_sec;
/* Size of struct to allocate for diameters private statistics, see ogs_diam_stats_ctx_t.
* Defaults to 0, no priv_stats allocated. */
size_t priv_stats_size;
} ogs_diam_config_stats_t;
/* This is default diameter configuration if there is no config file

View file

@ -36,6 +36,12 @@ int ogs_diam_stats_init(int mode, const ogs_diam_config_stats_t *config)
self.poll.timer = ogs_timer_add(ogs_app()->timer_mgr,
diam_stats_timer_cb, 0);
ogs_assert(self.poll.timer);
if (config->priv_stats_size > 0) {
self.priv_stats_size = config->priv_stats_size;
self.priv_stats = ogs_calloc(1, self.priv_stats_size);
self.priv_stats_copy = ogs_calloc(1, self.priv_stats_size);
ogs_assert(self.priv_stats);
}
CHECK_POSIX( pthread_mutex_init(&self.stats_lock, NULL) );
@ -47,6 +53,13 @@ void ogs_diam_stats_final()
if (self.poll.timer)
ogs_timer_delete(self.poll.timer);
self.poll.timer = NULL;
if (self.priv_stats) {
ogs_free(self.priv_stats);
ogs_free(self.priv_stats_copy);
self.priv_stats = NULL;
self.priv_stats_copy = NULL;
self.priv_stats_size = 0;
}
}
ogs_diam_stats_ctx_t* ogs_diam_stats_self()
@ -66,6 +79,16 @@ int ogs_diam_stats_start()
return 0;
}
void ogs_diam_stats_update_cb_register(ogs_diam_stats_update_cb cb)
{
self.update_cb = cb;
}
void ogs_diam_stats_update_cb_unregister(void)
{
self.update_cb = NULL;
}
static void ogs_diam_stats_log(const ogs_diam_stats_t *stats, ogs_time_t elapsed)
{
ogs_trace("------- fd statistics ---------");
@ -101,6 +124,8 @@ static void diam_stats_timer_cb(void *data)
/* Now, get the current stats */
CHECK_POSIX_DO( pthread_mutex_lock(&self.stats_lock), );
memcpy(&copy, &self.stats, sizeof(ogs_diam_stats_t));
if (self.priv_stats_copy)
memcpy(self.priv_stats_copy, self.priv_stats, self.priv_stats_size);
CHECK_POSIX_DO( pthread_mutex_unlock(&self.stats_lock), );
/* Get the current execution time */
@ -110,7 +135,12 @@ static void diam_stats_timer_cb(void *data)
/* Now, display everything */
ogs_diam_stats_log(&copy, since_start);
/* Trigger user callback: */
if (self.update_cb)
self.update_cb(&copy, self.priv_stats_copy);
/* Re-schedule timer: */
now = ogs_get_monotonic_time();
since_prev = now - self.poll.t_prev;
/* Avoid increasing drift: */
if (since_prev > self.poll.t_interval) {

View file

@ -40,6 +40,8 @@ typedef struct ogs_diam_stats_s {
unsigned long avg; /* average answer time, in microseconds */
} ogs_diam_stats_t;
typedef void (*ogs_diam_stats_update_cb)(const ogs_diam_stats_t *stats, const void *priv_stats);
typedef struct ogs_diam_stats_ctx_s {
#define FD_MODE_SERVER 0x1
@ -53,6 +55,10 @@ typedef struct ogs_diam_stats_ctx_s {
ogs_time_t t_interval; /* in usecs */
} poll;
ogs_diam_stats_t stats;
void *priv_stats; /* if !NULL, allocated struct of size "priv_stats_size" */
size_t priv_stats_size;
void *priv_stats_copy; /* buffer where priv_state are copied and passed to update_cb */
ogs_diam_stats_update_cb update_cb;
pthread_mutex_t stats_lock;
} ogs_diam_stats_ctx_t;
@ -64,6 +70,9 @@ ogs_diam_stats_ctx_t* ogs_diam_stats_self(void);
int ogs_diam_stats_start(void);
void ogs_diam_stats_update_cb_register(ogs_diam_stats_update_cb cb);
void ogs_diam_stats_update_cb_unregister(void);
#ifdef __cplusplus
}
#endif