Skip to content

Commit b8e0744

Browse files
committed
out_s3: add time offset support for s3 key format
The S3 key format is not time zone aware, which makes it hard to use when logs need to be stored in a different timezone than the S3 bucket's default. This patch adds support for a configurable time offset in the S3 key format. The offset is specified as a string like +0100 or -0100, following the same convention used in other parse configuration parameters. Signed-off-by: Fan Zhuang <[email protected]>
1 parent 610a125 commit b8e0744

File tree

6 files changed

+206
-20
lines changed

6 files changed

+206
-20
lines changed

include/fluent-bit/flb_aws_util.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ int flb_read_file(const char *path, char **out_buf, size_t *out_size);
194194

195195
/* Constructs S3 object key as per the format. */
196196
flb_sds_t flb_get_s3_key(const char *format, time_t time, const char *tag,
197-
char *tag_delimiter, uint64_t seq_index);
197+
char *tag_delimiter, uint64_t seq_index, const char *time_offset);
198198

199199
/* Constructs S3 object key as per the blob format. */
200200
flb_sds_t flb_get_s3_blob_key(const char *format, const char *tag,
@@ -208,5 +208,12 @@ flb_sds_t flb_get_s3_blob_key(const char *format, const char *tag,
208208
size_t flb_aws_strftime_precision(char **out_buf, const char *time_format,
209209
struct flb_time *tms);
210210

211+
212+
/*
213+
* Parses the time offset and returns the offset in seconds.
214+
*/
215+
size_t flb_aws_parse_tz_offset(const char *time_offset);
216+
217+
211218
#endif
212219
#endif /* FLB_HAVE_AWS */

plugins/out_s3/s3.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1460,7 +1460,7 @@ static int s3_put_object(struct flb_s3 *ctx, const char *tag, time_t file_first_
14601460
char final_body_md5[25];
14611461

14621462
s3_key = flb_get_s3_key(ctx->s3_key_format, file_first_log_time, tag,
1463-
ctx->tag_delimiters, ctx->seq_index);
1463+
ctx->tag_delimiters, ctx->seq_index, ctx->time_offset);
14641464
if (!s3_key) {
14651465
flb_plg_error(ctx->ins, "Failed to construct S3 Object Key for %s", tag);
14661466
return -1;
@@ -1648,7 +1648,7 @@ static struct multipart_upload *create_upload(struct flb_s3 *ctx, const char *ta
16481648
return NULL;
16491649
}
16501650
s3_key = flb_get_s3_key(ctx->s3_key_format, file_first_log_time, tag,
1651-
ctx->tag_delimiters, ctx->seq_index);
1651+
ctx->tag_delimiters, ctx->seq_index, ctx->time_offset);
16521652
if (!s3_key) {
16531653
flb_plg_error(ctx->ins, "Failed to construct S3 Object Key for %s", tag);
16541654
flb_free(m_upload);
@@ -4034,6 +4034,14 @@ static struct flb_config_map config_map[] = {
40344034
"documentation."
40354035
},
40364036

4037+
{
4038+
FLB_CONFIG_MAP_STR, "time_offset", "+0000",
4039+
0, FLB_TRUE, offsetof(struct flb_s3, time_offset),
4040+
"Time offset to apply to the s3 key format. This is useful when the s3 key format is "
4041+
"in a different timezone than the S3 bucket. The format is +HHMM or -HHMM. "
4042+
"Default is +0000."
4043+
},
4044+
40374045
{
40384046
FLB_CONFIG_MAP_STR, "s3_key_format_tag_delimiters", ".",
40394047
0, FLB_TRUE, offsetof(struct flb_s3, tag_delimiters),

plugins/out_s3/s3.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ struct flb_s3 {
105105
char *bucket;
106106
char *region;
107107
char *s3_key_format;
108+
char *time_offset;
108109
char *tag_delimiters;
109110
char *endpoint;
110111
char *sts_endpoint;
@@ -113,7 +114,7 @@ struct flb_s3 {
113114
char *storage_class;
114115
char *log_key;
115116
char *external_id;
116-
char *profile;
117+
char *profile;
117118
int free_endpoint;
118119
int retry_requests;
119120
int use_put_object;

src/aws/flb_aws_util.c

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,12 @@
2727
#include <fluent-bit/flb_jsmn.h>
2828
#include <fluent-bit/flb_env.h>
2929

30+
#include <stddef.h>
3031
#include <stdlib.h>
3132
#include <sys/types.h>
3233
#include <sys/stat.h>
3334
#include <fcntl.h>
35+
#include <ctype.h>
3436

3537
#define AWS_SERVICE_ENDPOINT_FORMAT "%s.%s.amazonaws.com"
3638
#define AWS_SERVICE_ENDPOINT_BASE_LEN 15
@@ -1009,7 +1011,7 @@ flb_sds_t flb_get_s3_blob_key(const char *format,
10091011

10101012
/* Constructs S3 object key as per the format. */
10111013
flb_sds_t flb_get_s3_key(const char *format, time_t time, const char *tag,
1012-
char *tag_delimiter, uint64_t seq_index)
1014+
char *tag_delimiter, uint64_t seq_index, const char *time_offset)
10131015
{
10141016
int i = 0;
10151017
int ret = 0;
@@ -1027,6 +1029,13 @@ flb_sds_t flb_get_s3_key(const char *format, time_t time, const char *tag,
10271029
flb_sds_t tmp_key = NULL;
10281030
flb_sds_t tmp_tag = NULL;
10291031
struct tm gmt = {0};
1032+
size_t tz_offset = 0;
1033+
1034+
tz_offset = flb_aws_parse_tz_offset(time_offset);
1035+
1036+
if (tz_offset != 0) {
1037+
time += tz_offset;
1038+
}
10301039

10311040
if (strlen(format) > S3_KEY_SIZE){
10321041
flb_warn("[s3_key] Object key length is longer than the 1024 character limit.");
@@ -1324,3 +1333,38 @@ size_t flb_aws_strftime_precision(char **out_buf, const char *time_format,
13241333

13251334
return out_size;
13261335
}
1336+
1337+
1338+
size_t flb_aws_parse_tz_offset(const char *time_offset) {
1339+
int sign, hh, mm;
1340+
1341+
if (!time_offset) {
1342+
return 0;
1343+
}
1344+
1345+
if (strlen(time_offset) < 5) {
1346+
return 0;
1347+
}
1348+
1349+
if (time_offset[0] != '+' && time_offset[0] != '-') {
1350+
return 0;
1351+
}
1352+
1353+
sign = (time_offset[0] == '+') ? 1 : -1;
1354+
1355+
if (!isdigit(time_offset[1]) ||
1356+
!isdigit(time_offset[2]) ||
1357+
!isdigit(time_offset[3]) ||
1358+
!isdigit(time_offset[4])) {
1359+
return 0;
1360+
}
1361+
1362+
hh = ((time_offset[1] - '0') * 10) + (time_offset[2] - '0');
1363+
mm = ((time_offset[3] - '0') * 10) + (time_offset[4] - '0');
1364+
1365+
if (hh < 0 || hh > 23 || mm < 0 || mm > 59) {
1366+
return 0;
1367+
}
1368+
1369+
return sign * (hh * 3600 + mm * 60);
1370+
}

0 commit comments

Comments
 (0)