Coverage Report

Created: 2026-03-22 07:09

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/fluent-bit/plugins/in_fluentbit_metrics/metrics.c
Line
Count
Source
1
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3
/*  Fluent Bit
4
 *  ==========
5
 *  Copyright (C) 2015-2026 The Fluent Bit Authors
6
 *
7
 *  Licensed under the Apache License, Version 2.0 (the "License");
8
 *  you may not use this file except in compliance with the License.
9
 *  You may obtain a copy of the License at
10
 *
11
 *      http://www.apache.org/licenses/LICENSE-2.0
12
 *
13
 *  Unless required by applicable law or agreed to in writing, software
14
 *  distributed under the License is distributed on an "AS IS" BASIS,
15
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
 *  See the License for the specific language governing permissions and
17
 *  limitations under the License.
18
 */
19
20
#include <fluent-bit/flb_input_plugin.h>
21
#include <fluent-bit/flb_config.h>
22
#include <fluent-bit/flb_metrics.h>
23
#include <fluent-bit/flb_metrics_exporter.h>
24
25
struct flb_in_metrics {
26
    /* config map options */
27
    int scrape_on_start;
28
    int scrape_interval;
29
30
    /* internal */
31
    int coll_fd_start;
32
    int coll_fd_runtime;
33
    struct cmt_counter *c;
34
    struct flb_input_instance *ins;
35
};
36
37
static int scrape_metrics(struct flb_config *config, struct flb_in_metrics *ctx)
38
0
{
39
0
    int ret;
40
0
    size_t ts;
41
0
    char *name;
42
0
    struct cmt *cmt;
43
44
    /* Update internal metric */
45
0
    ts = cfl_time_now();
46
0
    name = (char *) flb_input_name(ctx->ins);
47
0
    cmt_counter_inc(ctx->c, ts, 1, (char *[]) {name});
48
49
50
0
    cmt = flb_me_get_cmetrics(config);
51
0
    if (!cmt) {
52
0
        flb_plg_error(ctx->ins, "could not scrape metrics");
53
0
        return 0;
54
0
    }
55
56
    /* Append the updated metrics */
57
0
    ret = flb_input_metrics_append(ctx->ins, NULL, 0, cmt);
58
0
    if (ret != 0) {
59
0
        flb_plg_error(ctx->ins, "could not append metrics");
60
0
    }
61
0
    cmt_destroy(cmt);
62
63
0
    return 0;
64
0
}
65
66
/*
67
 * Update the metrics, this function is invoked every time 'scrape_interval'
68
 * expires.
69
 */
70
static int cb_metrics_collect_runtime(struct flb_input_instance *ins,
71
                                      struct flb_config *config, void *in_context)
72
0
{
73
0
    return scrape_metrics(config, in_context);
74
0
}
75
76
static int cb_metrics_collect_start(struct flb_input_instance *ins,
77
                                    struct flb_config *config, void *in_context)
78
0
{
79
0
    struct flb_in_metrics *ctx = in_context;
80
81
    /* pause collector */
82
0
    flb_input_collector_pause(ctx->coll_fd_start, ctx->ins);
83
84
0
    return scrape_metrics(config, ctx);
85
0
}
86
87
static int in_metrics_init(struct flb_input_instance *in,
88
                           struct flb_config *config, void *data)
89
0
{
90
0
    int ret;
91
0
    struct flb_in_metrics *ctx;
92
93
    /* Create plugin context */
94
0
    ctx = flb_calloc(1, sizeof(struct flb_in_metrics));
95
0
    if (!ctx) {
96
0
        flb_errno();
97
0
        return -1;
98
0
    }
99
0
    ctx->ins = in;
100
101
    /* Load the config map */
102
0
    ret = flb_input_config_map_set(in, (void *) ctx);
103
0
    if (ret == -1) {
104
0
        flb_free(ctx);
105
0
        return -1;
106
0
    }
107
108
    /* Associate context with the instance */
109
0
    flb_input_set_context(in, ctx);
110
111
    /* Scrape metrics on start / collector */
112
0
    if (ctx->scrape_interval > 2 && ctx->scrape_on_start) {
113
0
        ret = flb_input_set_collector_time(in,
114
0
                                           cb_metrics_collect_start,
115
0
                                           5, 0,
116
0
                                           config);
117
0
        if (ret == -1) {
118
0
            flb_plg_error(ctx->ins,
119
0
                          "could not set collector on start for Fluent Bit "
120
0
                          "metrics plugin");
121
0
            flb_free(ctx);
122
0
            return -1;
123
0
        }
124
0
        ctx->coll_fd_start = ret;
125
0
    }
126
127
    /* Create the runtime collector */
128
0
    ret = flb_input_set_collector_time(in,
129
0
                                       cb_metrics_collect_runtime,
130
0
                                       ctx->scrape_interval, 0,
131
0
                                       config);
132
0
    if (ret == -1) {
133
0
        flb_plg_error(ctx->ins,
134
0
                      "could not set collector for Fluent Bit metrics plugin");
135
0
        flb_free(ctx);
136
0
        return -1;
137
0
    }
138
0
    ctx->coll_fd_runtime = ret;
139
140
    /* Internal metrics */
141
0
    ctx->c = cmt_counter_create(ctx->ins->cmt,
142
0
                                "fluentbit", "input_metrics", "scrapes_total",
143
0
                                "Number of total metrics scrapes",
144
0
                                1, (char *[]) {"name"});
145
0
    return 0;
146
0
}
147
148
static int in_metrics_exit(void *data, struct flb_config *config)
149
0
{
150
0
    struct flb_in_metrics *ctx = data;
151
152
0
    if (!ctx) {
153
0
        return 0;
154
0
    }
155
156
0
    flb_free(ctx);
157
0
    return 0;
158
0
}
159
160
static void in_metrics_pause(void *data, struct flb_config *config)
161
0
{
162
0
    struct flb_in_metrics *ctx = data;
163
164
0
    flb_input_collector_pause(ctx->coll_fd_runtime, ctx->ins);
165
0
}
166
167
static void in_metrics_resume(void *data, struct flb_config *config)
168
0
{
169
0
    struct flb_in_metrics *ctx = data;
170
171
0
    flb_input_collector_resume(ctx->coll_fd_runtime, ctx->ins);
172
0
}
173
174
/* Configuration properties map */
175
static struct flb_config_map config_map[] = {
176
    {
177
     FLB_CONFIG_MAP_TIME, "scrape_interval", "2",
178
     0, FLB_TRUE, offsetof(struct flb_in_metrics, scrape_interval),
179
     "scrape interval to collect the internal metrics of Fluent Bit."
180
    },
181
182
    {
183
     FLB_CONFIG_MAP_BOOL, "scrape_on_start", "false",
184
     0, FLB_TRUE, offsetof(struct flb_in_metrics, scrape_on_start),
185
     "scrape metrics upon start, useful to avoid waiting for 'scrape_interval' "
186
     "for the first round of metrics."
187
    },
188
189
    /* EOF */
190
    {0}
191
};
192
193
struct flb_input_plugin in_fluentbit_metrics_plugin = {
194
    .name         = "fluentbit_metrics",
195
    .description  = "Fluent Bit internal metrics",
196
    .cb_init      = in_metrics_init,
197
    .cb_pre_run   = NULL,
198
    .cb_flush_buf = NULL,
199
    .config_map   = config_map,
200
    .cb_pause     = in_metrics_pause,
201
    .cb_resume    = in_metrics_resume,
202
    .cb_exit      = in_metrics_exit,
203
};