1 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3 /* Fluent Bit
4 * ==========
5 * Copyright (C) 2019-2021 The Fluent Bit Authors
6 * Copyright (C) 2015-2018 Treasure Data Inc.
7 *
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 */
20
21 #include <fluent-bit/flb_output_plugin.h>
22 #include <fluent-bit/flb_pack.h>
23
24 #include <stdio.h>
25 #include <unistd.h>
26 #include <fcntl.h>
27
28
29 /* Retry context, only works with one instance */
30 struct retry_ctx {
31 int n_retry; /* max retries before real flush (OK) */
32 int count; /* number of retries done */
33 struct flb_output_instance *ins; /* plugin instance */
34 };
35
36
cb_retry_init(struct flb_output_instance * ins,struct flb_config * config,void * data)37 static int cb_retry_init(struct flb_output_instance *ins,
38 struct flb_config *config,
39 void *data)
40 {
41 (void) config;
42 (void) data;
43 const char *tmp;
44 struct retry_ctx *ctx;
45
46 ctx = flb_calloc(1, sizeof(struct retry_ctx));
47 if (!ctx) {
48 return -1;
49 }
50 ctx->ins = ins;
51 ctx->count = 0;
52
53 tmp = flb_output_get_property("retries", ins);
54 if (!tmp) {
55 ctx->n_retry = 3;
56 }
57 else {
58 ctx->n_retry = atoi(tmp);
59 }
60
61 flb_output_set_context(ins, ctx);
62 return 0;
63 }
64
cb_retry_flush(const void * data,size_t bytes,const char * tag,int tag_len,struct flb_input_instance * i_ins,void * out_context,struct flb_config * config)65 static void cb_retry_flush(const void *data, size_t bytes,
66 const char *tag, int tag_len,
67 struct flb_input_instance *i_ins,
68 void *out_context,
69 struct flb_config *config)
70 {
71 (void) data;
72 (void) bytes;
73 (void) tag;
74 (void) tag_len;
75 (void) i_ins;
76 (void) out_context;
77 (void) config;
78 struct retry_ctx *ctx;
79
80 ctx = out_context;
81 ctx->count++;
82
83 if (ctx->count <= ctx->n_retry) {
84 flb_plg_debug(ctx->ins, "retry %i/%i", ctx->count, ctx->n_retry);
85 FLB_OUTPUT_RETURN(FLB_RETRY);
86 }
87 else {
88 flb_plg_debug(ctx->ins, "flush", ctx->count, ctx->n_retry);
89 ctx->count = 0;
90 }
91
92 flb_pack_print(data, bytes);
93 FLB_OUTPUT_RETURN(FLB_OK);
94 }
95
cb_retry_exit(void * data,struct flb_config * config)96 static int cb_retry_exit(void *data, struct flb_config *config)
97 {
98 struct retry_ctx *ctx = data;
99 (void) config;
100
101 flb_free(ctx);
102 return 0;
103 }
104
105 struct flb_output_plugin out_retry_plugin = {
106 .name = "retry",
107 .description = "Issue a retry upon flush request",
108 .cb_init = cb_retry_init,
109 .cb_flush = cb_retry_flush,
110 .cb_exit = cb_retry_exit,
111 .flags = 0,
112 };
113