summaryrefslogtreecommitdiffstats
path: root/src/fluent-bit/plugins/out_oracle_log_analytics
diff options
context:
space:
mode:
Diffstat (limited to 'src/fluent-bit/plugins/out_oracle_log_analytics')
-rw-r--r--src/fluent-bit/plugins/out_oracle_log_analytics/CMakeLists.txt6
-rw-r--r--src/fluent-bit/plugins/out_oracle_log_analytics/oci_logan.c1313
-rw-r--r--src/fluent-bit/plugins/out_oracle_log_analytics/oci_logan.h215
-rw-r--r--src/fluent-bit/plugins/out_oracle_log_analytics/oci_logan_conf.c493
-rw-r--r--src/fluent-bit/plugins/out_oracle_log_analytics/oci_logan_conf.h34
5 files changed, 2061 insertions, 0 deletions
diff --git a/src/fluent-bit/plugins/out_oracle_log_analytics/CMakeLists.txt b/src/fluent-bit/plugins/out_oracle_log_analytics/CMakeLists.txt
new file mode 100644
index 000000000..81f971a95
--- /dev/null
+++ b/src/fluent-bit/plugins/out_oracle_log_analytics/CMakeLists.txt
@@ -0,0 +1,6 @@
+set(src
+ oci_logan.c
+ oci_logan_conf.c
+ )
+
+FLB_PLUGIN(out_oracle_log_analytics "${src}" "")
diff --git a/src/fluent-bit/plugins/out_oracle_log_analytics/oci_logan.c b/src/fluent-bit/plugins/out_oracle_log_analytics/oci_logan.c
new file mode 100644
index 000000000..630812e2d
--- /dev/null
+++ b/src/fluent-bit/plugins/out_oracle_log_analytics/oci_logan.c
@@ -0,0 +1,1313 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+
+/* Fluent Bit
+ * ==========
+ * Copyright (C) 2015-2023 The Fluent Bit Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#include <fluent-bit/flb_output_plugin.h>
+#include <fluent-bit/flb_upstream.h>
+#include <fluent-bit/flb_upstream_conn.h>
+#include <fluent-bit/flb_http_client.h>
+#include <fluent-bit/flb_log_event_decoder.h>
+#include <fluent-bit/flb_hash_table.h>
+#include <fluent-bit/flb_pack.h>
+#include <fluent-bit/flb_crypto.h>
+#include <fluent-bit/flb_base64.h>
+#include <fluent-bit/flb_hash.h>
+#include <fluent-bit/flb_sds.h>
+
+#include <monkey/mk_core/mk_list.h>
+#include <msgpack.h>
+
+#include <string.h>
+
+#include "oci_logan_conf.h"
+#include "oci_logan.h"
+
+
+static int check_config_from_record(msgpack_object key,
+ char *name, int len)
+{
+ if (key.type != MSGPACK_OBJECT_STR) {
+ return FLB_FALSE;
+ }
+
+ if (key.via.str.size != len) {
+ return FLB_FALSE;
+ }
+
+
+ return memcmp(key.via.str.ptr, name, len) == 0;
+}
+
+/*
+ * Authorization: Signature version="1",keyId="<tenancy_ocid>/<user_ocid>/<key_fingerprint>",
+ * algorithm="rsa-sha256",headers="(request-target) date x-content-sha256 content-type content-length",
+ * signature="signature"
+ */
+static flb_sds_t create_authorization_header_content(struct flb_oci_logan *ctx,
+ flb_sds_t signature)
+{
+ flb_sds_t content;
+
+ content = flb_sds_create_size(512);
+ flb_sds_cat_safe(&content, FLB_OCI_SIGN_SIGNATURE_VERSION,
+ sizeof(FLB_OCI_SIGN_SIGNATURE_VERSION) - 1);
+ flb_sds_cat_safe(&content, ",", 1);
+ flb_sds_cat_safe(&content, FLB_OCI_SIGN_KEYID,
+ sizeof(FLB_OCI_SIGN_KEYID) - 1);
+ flb_sds_cat_safe(&content, "=\"", 2);
+ flb_sds_cat_safe(&content, ctx->key_id, flb_sds_len(ctx->key_id));
+ flb_sds_cat_safe(&content, "\",", 2);
+ flb_sds_cat_safe(&content, FLB_OCI_SIGN_ALGORITHM,
+ sizeof(FLB_OCI_SIGN_ALGORITHM) - 1);
+ flb_sds_cat_safe(&content, ",", 1);
+ flb_sds_cat_safe(&content, FLB_OCI_SIGN_HEADERS,
+ sizeof(FLB_OCI_SIGN_HEADERS) - 1);
+ flb_sds_cat_safe(&content, ",", 1);
+ flb_sds_cat_safe(&content, FLB_OCI_SIGN_SIGNATURE,
+ sizeof(FLB_OCI_SIGN_SIGNATURE) - 1);
+ flb_sds_cat_safe(&content, "=\"", 2);
+ flb_sds_cat_safe(&content, signature, flb_sds_len(signature));
+ flb_sds_cat_safe(&content, "\"", 1);
+
+ return content;
+}
+
+static flb_sds_t create_base64_sha256_signature(struct flb_oci_logan *ctx,
+ flb_sds_t signing_string)
+{
+ int len = 0, ret;
+ size_t outlen;
+ flb_sds_t signature;
+ unsigned char sha256_buf[32] = { 0 };
+ unsigned char sig[256] = { 0 };
+ size_t sig_len = sizeof(sig);
+
+ ret = flb_hash_simple(FLB_HASH_SHA256,
+ (unsigned char*) signing_string,
+ flb_sds_len(signing_string),
+ sha256_buf, sizeof(sha256_buf));
+
+ if(ret != FLB_CRYPTO_SUCCESS) {
+ flb_plg_error(ctx->ins, "error generating hash buffer");
+ return NULL;
+ }
+
+ ret = flb_crypto_sign_simple(FLB_CRYPTO_PRIVATE_KEY,
+ FLB_CRYPTO_PADDING_PKCS1,
+ FLB_HASH_SHA256,
+ (unsigned char *) ctx->private_key,
+ flb_sds_len(ctx->private_key),
+ sha256_buf, sizeof(sha256_buf),
+ sig, &sig_len);
+
+
+ if (ret != FLB_CRYPTO_SUCCESS) {
+ flb_plg_error(ctx->ins, "error signing SHA256");
+ return NULL;
+ }
+
+ signature = flb_sds_create_size(512);
+ if (!signature) {
+ flb_errno();
+ return NULL;
+ }
+
+ /* base 64 encode */
+ len = flb_sds_alloc(signature) - 1;
+ flb_base64_encode((unsigned char*) signature, len, &outlen, sig,
+ sizeof(sig));
+ signature[outlen] = '\0';
+ flb_sds_len_set(signature, outlen);
+
+ return signature;
+}
+
+static flb_sds_t get_date(void)
+{
+
+ flb_sds_t rfc1123date;
+ time_t t;
+ size_t size;
+ struct tm tm = { 0 };
+
+ /* Format Date */
+ rfc1123date = flb_sds_create_size(32);
+ if (!rfc1123date) {
+ flb_errno();
+ return NULL;
+ }
+
+ t = time(NULL);
+ if (!gmtime_r(&t, &tm)) {
+ flb_errno();
+ flb_sds_destroy(rfc1123date);
+ return NULL;
+ }
+ size = strftime(rfc1123date, flb_sds_alloc(rfc1123date) - 1,
+ "%a, %d %b %Y %H:%M:%S GMT", &tm);
+ if (size <= 0) {
+ flb_errno();
+ flb_sds_destroy(rfc1123date);
+ return NULL;
+ }
+ flb_sds_len_set(rfc1123date, size);
+ return rfc1123date;
+}
+
+static flb_sds_t add_header_and_signing(struct flb_http_client *c,
+ flb_sds_t signing_str, const char *header, int headersize,
+ const char *val, int val_size)
+{
+ if (!signing_str) {
+ return NULL;
+ }
+
+ flb_http_add_header(c, header, headersize, val, val_size);
+
+ flb_sds_cat_safe(&signing_str, "\n", 1);
+ flb_sds_cat_safe(&signing_str, header, headersize);
+ flb_sds_cat_safe(&signing_str, ": ", 2);
+ flb_sds_cat_safe(&signing_str, val, val_size);
+
+ return signing_str;
+}
+
+static int build_headers(struct flb_http_client *c, struct flb_oci_logan *ctx,
+ flb_sds_t json, flb_sds_t hostname, int port, flb_sds_t uri)
+{
+ int ret = -1;
+ flb_sds_t tmp_sds = NULL;
+ flb_sds_t signing_str = NULL;
+ flb_sds_t rfc1123date = NULL;
+ flb_sds_t encoded_uri = NULL;
+ flb_sds_t signature = NULL;
+ flb_sds_t auth_header_str = NULL;
+
+ flb_sds_t tmp_ref = NULL;
+
+ size_t tmp_len = 0;
+
+ unsigned char sha256_buf[32] = { 0 };
+
+ tmp_sds = flb_sds_create_size(512);
+ if (!tmp_sds) {
+ flb_errno();
+ goto error_label;
+ }
+
+ signing_str = flb_sds_create_size(1024);
+ if (!signing_str) {
+ flb_errno();
+ goto error_label;
+ }
+
+ /* Add (requeset-target) to signing string */
+ encoded_uri = flb_uri_encode(uri, flb_sds_len(uri));
+ if (!encoded_uri) {
+ flb_errno();
+ goto error_label;
+ }
+ flb_sds_cat_safe(&signing_str, FLB_OCI_HEADER_REQUEST_TARGET,
+ sizeof(FLB_OCI_HEADER_REQUEST_TARGET) - 1);
+ flb_sds_cat_safe(&signing_str, ": post ", sizeof(": post ") - 1);
+ flb_sds_cat_safe(&signing_str, encoded_uri,
+ flb_sds_len(encoded_uri));
+
+ /* Add Host to Header */
+ if (((c->flags & FLB_IO_TLS) && c->port == 443)
+ || (!(c->flags & FLB_IO_TLS) && c->port == 80)) {
+ /* default port */
+ tmp_ref = flb_sds_copy(tmp_sds, c->host, strlen(c->host));
+ }
+ else {
+ tmp_ref = flb_sds_printf(&tmp_sds, "%s:%i", c->host, c->port);
+ }
+ if (!tmp_ref) {
+ flb_plg_error(ctx->ins, "cannot compose temporary host header");
+ goto error_label;
+ }
+ tmp_sds = tmp_ref;
+ tmp_ref = NULL;
+
+ signing_str = add_header_and_signing(c, signing_str, FLB_OCI_HEADER_HOST,
+ sizeof(FLB_OCI_HEADER_HOST) - 1,
+ tmp_sds, flb_sds_len(tmp_sds));
+ if (!signing_str) {
+ flb_plg_error(ctx->ins, "cannot compose signing string");
+ goto error_label;
+ }
+
+ /* Add Date header */
+ rfc1123date = get_date();
+ if (!rfc1123date) {
+ flb_plg_error(ctx->ins, "cannot compose temporary date header");
+ goto error_label;
+ }
+ signing_str = add_header_and_signing(c, signing_str, FLB_OCI_HEADER_DATE,
+ sizeof(FLB_OCI_HEADER_DATE) - 1, rfc1123date,
+ flb_sds_len(rfc1123date));
+ if (!signing_str) {
+ flb_plg_error(ctx->ins, "cannot compose signing string");
+ goto error_label;
+ }
+
+ /* Add x-content-sha256 Header */
+ ret = flb_hash_simple(FLB_HASH_SHA256,
+ (unsigned char*) json,
+ flb_sds_len(json),
+ sha256_buf, sizeof(sha256_buf));
+
+ if (ret != FLB_CRYPTO_SUCCESS) {
+ flb_plg_error(ctx->ins, "error forming hash buffer for x-content-sha256 Header");
+ goto error_label;
+ }
+
+ flb_base64_encode((unsigned char*) tmp_sds, flb_sds_len(tmp_sds) - 1,
+ &tmp_len, sha256_buf, sizeof(sha256_buf));
+
+ tmp_sds[tmp_len] = '\0';
+ flb_sds_len_set(tmp_sds, tmp_len);
+
+ signing_str = add_header_and_signing(c, signing_str,
+ FLB_OCI_HEADER_X_CONTENT_SHA256,
+ sizeof(FLB_OCI_HEADER_X_CONTENT_SHA256) - 1, tmp_sds,
+ flb_sds_len(tmp_sds));
+ if (!signing_str) {
+ flb_plg_error(ctx->ins, "cannot compose signing string");
+ goto error_label;
+ }
+
+ /* Add content-Type */
+ signing_str = add_header_and_signing(c, signing_str,
+ FLB_OCI_HEADER_CONTENT_TYPE, sizeof(FLB_OCI_HEADER_CONTENT_TYPE) - 1,
+ FLB_OCI_HEADER_CONTENT_TYPE_VAL,
+ sizeof(FLB_OCI_HEADER_CONTENT_TYPE_VAL) - 1);
+ if (!signing_str) {
+ flb_plg_error(ctx->ins, "cannot compose signing string");
+ goto error_label;
+ }
+
+ /* Add content-Length */
+ tmp_len = snprintf(tmp_sds, flb_sds_alloc(tmp_sds) - 1, "%i",
+ (int) flb_sds_len(json));
+ flb_sds_len_set(tmp_sds, tmp_len);
+ signing_str = add_header_and_signing(c, signing_str,
+ FLB_OCI_HEADER_CONTENT_LENGTH, sizeof(FLB_OCI_HEADER_CONTENT_LENGTH) - 1,
+ tmp_sds, flb_sds_len(tmp_sds));
+ if (!signing_str) {
+ flb_plg_error(ctx->ins, "cannot compose signing string");
+ goto error_label;
+ }
+
+ /* Add Authorization header */
+ signature = create_base64_sha256_signature(ctx, signing_str);
+ if (!signature) {
+ flb_plg_error(ctx->ins, "cannot compose signing signature");
+ goto error_label;
+ }
+
+ auth_header_str = create_authorization_header_content(ctx, signature);
+ if (!auth_header_str) {
+ flb_plg_error(ctx->ins, "cannot compose authorization header");
+ goto error_label;
+ }
+
+ flb_http_add_header(c, FLB_OCI_HEADER_AUTH, sizeof(FLB_OCI_HEADER_AUTH) - 1,
+ auth_header_str, flb_sds_len(auth_header_str));
+
+ /* User-Agent */
+ flb_http_add_header(c, FLB_OCI_HEADER_USER_AGENT,
+ sizeof(FLB_OCI_HEADER_USER_AGENT) - 1,
+ FLB_OCI_HEADER_USER_AGENT_VAL,
+ sizeof(FLB_OCI_HEADER_USER_AGENT_VAL) - 1);
+
+ /* Accept */
+ flb_http_add_header(c, "Accept", 6, "*/*", 3);
+
+ ret = 0;
+
+ error_label:
+ if (tmp_sds) {
+ flb_sds_destroy(tmp_sds);
+ }
+ if (signing_str) {
+ flb_sds_destroy(signing_str);
+ }
+ if (rfc1123date) {
+ flb_sds_destroy(rfc1123date);
+ }
+ if (encoded_uri) {
+ flb_sds_destroy(encoded_uri);
+ }
+ if (signature) {
+ flb_sds_destroy(signature);
+ }
+ if (auth_header_str) {
+ flb_sds_destroy(auth_header_str);
+ }
+ return ret;
+}
+
+static struct flb_oci_error_response* parse_response_error(struct flb_oci_logan *ctx,
+ char *response, size_t response_len)
+{
+ int tok_size = 32, ret, i;
+ jsmn_parser parser;
+ jsmntok_t *t;
+ jsmntok_t *tokens;
+ char *key;
+ char *val;
+ int key_len;
+ int val_len;
+ struct flb_oci_error_response *error_response;
+
+ jsmn_init(&parser);
+
+ tokens = flb_calloc(1, sizeof(jsmntok_t) * tok_size);
+ if (!tokens) {
+ flb_errno();
+ return NULL;
+ }
+
+ ret = jsmn_parse(&parser, response, response_len, tokens, tok_size);
+
+ if (ret == JSMN_ERROR_INVAL || ret == JSMN_ERROR_PART) {
+ flb_free(tokens);
+ flb_plg_info(ctx->ins,
+ "Unable to parser error response. reponse is not valid json");
+ return NULL;
+ }
+ tok_size = ret;
+
+ error_response = flb_calloc(1, sizeof(struct flb_oci_error_response));
+ if (!error_response) {
+ flb_errno();
+ flb_free(tokens);
+ return NULL;
+ }
+
+ /* Parse JSON tokens */
+ for (i = 0; i < tok_size; i++) {
+ t = &tokens[i];
+
+ if (t->start == -1 || t->end == -1 || (t->start == 0 && t->end == 0)) {
+ break;
+ }
+
+ if (t->type != JSMN_STRING) {
+ continue;
+ }
+
+ key = response + t->start;
+ key_len = (t->end - t->start);
+
+ i++;
+ t = &tokens[i];
+ val = response + t->start;
+ val_len = (t->end - t->start);
+
+ if (val_len < 1) {
+ continue;
+ }
+
+ if ((key_len == sizeof(FLB_OCI_ERROR_RESPONSE_CODE) - 1)
+ && strncasecmp(key, FLB_OCI_ERROR_RESPONSE_CODE,
+ sizeof(FLB_OCI_ERROR_RESPONSE_CODE) - 1) == 0) {
+ /* code */
+ error_response->code = flb_sds_create_len(val, val_len);
+ if (!error_response->code) {
+ flb_free(error_response);
+ flb_free(tokens);
+ return NULL;
+ }
+ }
+ else if ((key_len == sizeof(FLB_OCI_ERROR_RESPONSE_MESSAGE) - 1)
+ && strncasecmp(key, FLB_OCI_ERROR_RESPONSE_MESSAGE,
+ sizeof(FLB_OCI_ERROR_RESPONSE_MESSAGE) - 1) == 0) {
+
+ /* message */
+ error_response->message = flb_sds_create_len(val, val_len);
+ if (!error_response->message) {
+ flb_free(error_response);
+ flb_free(tokens);
+ return NULL;
+ }
+ }
+ }
+
+ flb_free(tokens);
+ return error_response;
+}
+
+static int retry_error(struct flb_http_client *c, struct flb_oci_logan *ctx)
+{
+ struct flb_oci_error_response *error_response = NULL;
+ int tmp_len;
+ int ret = FLB_FALSE;
+
+ /* possible retry error message */
+ if ( !(c->resp.status == 400 || c->resp.status == 401
+ || c->resp.status == 404 || c->resp.status == 409
+ || c->resp.status == 429 || c->resp.status == 500)) {
+ return FLB_FALSE;
+ }
+
+ /* parse error message */
+ error_response = parse_response_error(ctx, c->resp.payload,
+ c->resp.payload_size);
+ if (!error_response) {
+ return FLB_FALSE;
+ }
+
+ if (error_response->code) {
+ tmp_len = flb_sds_len(error_response->code);
+ if (c->resp.status == 400
+ && (tmp_len == sizeof(FLB_OCI_ERROR_CODE_RELATED_RESOURCE_NOT_FOUND) - 1)
+ && strncasecmp(error_response->code, FLB_OCI_ERROR_CODE_RELATED_RESOURCE_NOT_FOUND, tmp_len) == 0) {
+ ret = FLB_TRUE;
+ }
+ else if( c->resp.status == 401
+ &&( tmp_len == sizeof(FLB_OCI_ERROR_CODE_NOT_AUTHENTICATED)-1 )
+ && strncasecmp(error_response->code, FLB_OCI_ERROR_CODE_NOT_AUTHENTICATED, tmp_len) == 0) {
+ ret = FLB_TRUE;
+ }
+ else if (c->resp.status == 404
+ && (tmp_len == sizeof(FLB_OCI_ERROR_CODE_NOT_AUTHENTICATEDORNOTFOUND) - 1)
+ && strncasecmp(error_response->code, FLB_OCI_ERROR_CODE_NOT_AUTHENTICATEDORNOTFOUND, tmp_len) == 0) {
+ ret = FLB_TRUE;
+ }
+ else if (c->resp.status == 409
+ && (tmp_len == sizeof(FLB_OCI_ERROR_CODE_INCORRECTSTATE) - 1)
+ && strncasecmp(error_response->code, FLB_OCI_ERROR_CODE_INCORRECTSTATE, tmp_len) == 0) {
+ ret = FLB_TRUE;
+ }
+ else if (c->resp.status == 409
+ && (tmp_len == sizeof(FLB_OCI_ERROR_CODE_NOT_AUTH_OR_RESOURCE_EXIST) - 1)
+ && strncasecmp(error_response->code, FLB_OCI_ERROR_CODE_NOT_AUTH_OR_RESOURCE_EXIST, tmp_len) == 0) {
+ ret = FLB_TRUE;
+ }
+ else if (c->resp.status == 429
+ && (tmp_len == sizeof(FLB_OCI_ERROR_CODE_TOO_MANY_REQUESTS) - 1)
+ && strncasecmp(error_response->code, FLB_OCI_ERROR_CODE_TOO_MANY_REQUESTS, tmp_len) == 0) {
+ ret = FLB_TRUE;
+ }
+ else if (c->resp.status == 500
+ && (tmp_len == sizeof(FLB_OCI_ERROR_CODE_INTERNAL_SERVER_ERROR) - 1)
+ && strncasecmp(error_response->code, FLB_OCI_ERROR_CODE_INTERNAL_SERVER_ERROR, tmp_len) == 0) {
+ ret = FLB_TRUE;
+ }
+ }
+
+ if (error_response->code) {
+ flb_sds_destroy(error_response->code);
+ }
+ if (error_response->message) {
+ flb_sds_destroy(error_response->message);
+ }
+ flb_free(error_response);
+
+ return ret;
+}
+
+static int cb_oci_logan_init(struct flb_output_instance *ins,
+ struct flb_config *config,
+ void *data)
+{
+ struct flb_oci_logan *ctx;
+ ctx = flb_oci_logan_conf_create(ins, config);
+ if (!ctx) {
+ flb_plg_error(ins, "cannot initialize plugin");
+ return -1;
+ }
+ flb_plg_info(ins, "initialized logan plugin");
+ flb_output_set_context(ins, ctx);
+ flb_output_set_http_debug_callbacks(ins);
+
+ return 0;
+}
+
+static flb_sds_t compose_uri(struct flb_oci_logan *ctx,
+ flb_sds_t log_set, flb_sds_t log_group_id)
+{
+ flb_sds_t uri_param;
+ flb_sds_t full_uri;
+
+ uri_param = flb_sds_create_size(512);
+ if (!uri_param) {
+ flb_errno();
+ return NULL;
+ }
+
+ /* LogGroupId */
+ if (log_group_id) {
+ if (flb_sds_len(uri_param) > 0) {
+ flb_sds_cat_safe(&uri_param, "&", 1);
+ }
+ flb_sds_cat_safe(&uri_param, FLB_OCI_LOG_GROUP_ID,
+ FLB_OCI_LOG_GROUP_ID_SIZE);
+ flb_sds_cat_safe(&uri_param, "=", 1);
+ flb_sds_cat_safe(&uri_param, log_group_id,
+ flb_sds_len(log_group_id));
+ }
+
+ if (!uri_param) {
+ return NULL;
+ }
+
+ /* logSet */
+ if (log_set) {
+ if (flb_sds_len(uri_param) > 0) {
+ flb_sds_cat_safe(&uri_param, "&", 1);
+ }
+ flb_sds_cat_safe(&uri_param, FLB_OCI_LOG_SET,
+ FLB_OCI_LOG_SET_SIZE);
+ flb_sds_cat_safe(&uri_param, "=", 1);
+ flb_sds_cat_safe(&uri_param, log_set,
+ flb_sds_len(log_set));
+ }
+
+ if (!uri_param) {
+ return NULL;
+ }
+
+ flb_sds_cat_safe(&uri_param, "&", 1);
+ flb_sds_cat_safe(&uri_param, FLB_OCI_PAYLOAD_TYPE,
+ sizeof(FLB_OCI_PAYLOAD_TYPE) - 1);
+ flb_sds_cat_safe(&uri_param, "=", 1);
+ flb_sds_cat_safe(&uri_param, "JSON", 4);
+
+
+ if (!uri_param) {
+ return NULL;
+ }
+
+
+ if (flb_sds_len(uri_param) == 0) {
+ flb_sds_destroy(uri_param);
+ return flb_sds_create(ctx->uri);
+ }
+
+ full_uri = flb_sds_create_size(
+ flb_sds_len(ctx->uri) + 1 + flb_sds_len(uri_param));
+ if (!full_uri) {
+ flb_errno();
+ flb_sds_destroy(uri_param);
+ return NULL;
+ }
+
+ flb_sds_cat_safe(&full_uri, ctx->uri, flb_sds_len(ctx->uri));
+ flb_sds_cat_safe(&full_uri, "?", 1);
+ flb_sds_cat_safe(&full_uri, uri_param, flb_sds_len(uri_param));
+
+ flb_sds_destroy(uri_param);
+
+ return full_uri;
+}
+
+static int flush_to_endpoint(struct flb_oci_logan *ctx,
+ flb_sds_t payload,
+ flb_sds_t log_group_id,
+ flb_sds_t log_set_id)
+{
+ int out_ret = FLB_RETRY;
+ int http_ret;
+ size_t b_sent;
+ flb_sds_t full_uri;
+ struct flb_http_client *c = NULL;
+ struct flb_connection *u_conn;
+
+ full_uri = compose_uri(ctx, log_set_id, log_group_id);
+ if(!full_uri) {
+ flb_plg_error(ctx->ins, "unable to compose uri for logGroup: %s logSet: %s",
+ ctx->oci_la_log_group_id, ctx->oci_la_log_set_id);
+ }
+
+ flb_plg_debug(ctx->ins, "full_uri=%s", full_uri);
+
+ u_conn = flb_upstream_conn_get(ctx->u);
+ if(!u_conn) {
+ goto error_label;
+ }
+ /* Create HTTP client context */
+ c = flb_http_client(u_conn, FLB_HTTP_POST, full_uri, (void*) payload,
+ flb_sds_len(payload), ctx->ins->host.name, ctx->ins->host.port, ctx->proxy, 0);
+ if (!c) {
+ goto error_label;
+ }
+ flb_http_allow_duplicated_headers(c, FLB_FALSE);
+
+ flb_plg_debug(ctx->ins, "built client");
+ flb_http_buffer_size(c, FLB_HTTP_DATA_SIZE_MAX);
+ if (build_headers(c, ctx, payload, ctx->ins->host.name, ctx->ins->host.port, full_uri) < 0) {
+ flb_plg_error(ctx->ins, "failed to build headers");
+ goto error_label;
+ }
+ flb_plg_debug(ctx->ins, "built request");
+
+ out_ret = FLB_OK;
+
+ http_ret = flb_http_do(c, &b_sent);
+ flb_plg_debug(ctx->ins, "placed request");
+
+ if (http_ret == 0) {
+
+ if (c->resp.status != 200) {
+ flb_plg_debug(ctx->ins, "request header %s", c->header_buf);
+
+ out_ret = FLB_ERROR;
+
+ if (c->resp.payload && c->resp.payload_size > 0) {
+ if (retry_error(c, ctx) == FLB_TRUE) {
+ out_ret = FLB_RETRY;
+ }
+
+ flb_plg_error(ctx->ins, "%s:%i, retry=%s, HTTP status=%i\n%s",
+ ctx->ins->host.name, ctx->ins->host.port,
+ (out_ret == FLB_RETRY ? "true" : "false"),
+ c->resp.status, c->resp.payload);
+ }
+ else {
+ flb_plg_error(ctx->ins, "%s:%i, retry=%s, HTTP status=%i",
+ ctx->ins->host.name, ctx->ins->host.port,
+ (out_ret == FLB_RETRY ? "true" : "false"),
+ c->resp.status);
+ }
+ }
+ }
+ else {
+ out_ret = FLB_RETRY;
+ flb_plg_error(ctx->ins, "could not flush records to %s:%i (http_do=%i), retry=%s",
+ ctx->ins->host.name, ctx->ins->host.port,
+ http_ret, (out_ret == FLB_RETRY ? "true" : "false"));
+ goto error_label;
+ }
+
+
+
+ error_label:
+ if (full_uri) {
+ flb_sds_destroy(full_uri);
+ }
+
+ /* Destroy HTTP client context */
+ if (c) {
+ flb_http_client_destroy(c);
+ }
+
+ /* Release the TCP connection */
+ if (u_conn) {
+ flb_upstream_conn_release(u_conn);
+ }
+
+ return out_ret;
+
+}
+
+static void pack_oci_fields(msgpack_packer *packer,
+ struct flb_oci_logan *ctx)
+{
+ int num_global_meta = 0;
+ int num_event_meta = 0;
+ int pck_sz = 2;
+ struct mk_list *head = NULL;
+ struct metadata_obj *f;
+
+
+ /* number of meta properties */
+ if(ctx->oci_la_global_metadata != NULL) {
+ num_global_meta = mk_list_size(&ctx->global_metadata_fields);
+ }
+ if(ctx->oci_la_metadata != NULL) {
+ num_event_meta = mk_list_size(&ctx->log_event_metadata_fields);
+ }
+
+
+ if (num_global_meta > 0) {
+ msgpack_pack_map(packer, 2);
+ msgpack_pack_str(packer, FLB_OCI_LOG_METADATA_SIZE);
+ msgpack_pack_str_body(packer, FLB_OCI_LOG_METADATA,
+ FLB_OCI_LOG_METADATA_SIZE);
+
+ msgpack_pack_map(packer, num_global_meta);
+ /* pack kv list */
+ mk_list_foreach(head, &ctx->global_metadata_fields) {
+ f = mk_list_entry(head, struct metadata_obj, _head);
+
+ msgpack_pack_str(packer, flb_sds_len(f->key));
+ msgpack_pack_str_body(packer, f->key, flb_sds_len(f->key));
+
+ msgpack_pack_str(packer, flb_sds_len(f->val));
+ msgpack_pack_str_body(packer, f->val, flb_sds_len(f->val));
+
+ }
+
+ }
+ else {
+ msgpack_pack_map(packer, 1);
+ }
+
+ /*
+ *logEvents":[
+ {
+ "entityId":"",
+ "logSourceName":"LinuxSyslogSource",
+ "logPath":"/var/log/messages",
+ "metadata":{
+ "Error ID":"1",
+ "Environment":"prod",
+ "Client Host Region":"PST"
+ },
+ "logRecords":[
+ "May 8 2017 04:02:36 blr00akm syslogd 1.4.1: shutdown.",
+ "May 8 2017 04:02:37 blr00akm syslogd 1.4.1: restart."
+ ]
+ },
+ {
+
+ }
+ ]
+ */
+ msgpack_pack_str(packer, FLB_OCI_LOG_EVENTS_SIZE);
+ msgpack_pack_str_body(packer, FLB_OCI_LOG_EVENTS, FLB_OCI_LOG_EVENTS_SIZE);
+
+ msgpack_pack_array(packer, 1);
+
+ if (ctx->oci_la_entity_id) {
+ pck_sz++;
+ }
+ if (ctx->oci_la_log_path) {
+ pck_sz++;
+ }
+ if (ctx->oci_la_entity_type) {
+ pck_sz++;
+ }
+
+ if (num_event_meta > 0) {
+ pck_sz++;
+ }
+
+ msgpack_pack_map(packer, pck_sz); /* entityId, logSourceName, logPath, logRecords */
+
+
+ /* "entityType:"" */
+ if (ctx->oci_la_entity_type) {
+ msgpack_pack_str(packer, FLB_OCI_ENTITY_TYPE_SIZE);
+ msgpack_pack_str_body(packer, FLB_OCI_ENTITY_TYPE, FLB_OCI_ENTITY_TYPE_SIZE);
+ msgpack_pack_str(packer, flb_sds_len(ctx->oci_la_entity_type));
+ msgpack_pack_str_body(packer, ctx->oci_la_entity_type,
+ flb_sds_len(ctx->oci_la_entity_type));
+ }
+
+ /* "entityId":"", */
+ if (ctx->oci_la_entity_id) {
+ msgpack_pack_str(packer, FLB_OCI_ENTITY_ID_SIZE);
+ msgpack_pack_str_body(packer, FLB_OCI_ENTITY_ID, FLB_OCI_ENTITY_ID_SIZE);
+ msgpack_pack_str(packer, flb_sds_len(ctx->oci_la_entity_id));
+ msgpack_pack_str_body(packer, ctx->oci_la_entity_id,
+ flb_sds_len(ctx->oci_la_entity_id));
+ }
+
+
+ /* "logSourceName":"", */
+ msgpack_pack_str(packer, FLB_OCI_LOG_SOURCE_NAME_SIZE);
+ msgpack_pack_str_body(packer, FLB_OCI_LOG_SOURCE_NAME,
+ FLB_OCI_LOG_SOURCE_NAME_SIZE);
+ msgpack_pack_str(packer, flb_sds_len(ctx->oci_la_log_source_name));
+ msgpack_pack_str_body(packer, ctx->oci_la_log_source_name,
+ flb_sds_len(ctx->oci_la_log_source_name));
+
+
+ /* "logPath":"" */
+ if (ctx->oci_la_log_path) {
+ msgpack_pack_str(packer, FLB_OCI_LOG_PATH_SIZE);
+ msgpack_pack_str_body(packer, FLB_OCI_LOG_PATH, FLB_OCI_LOG_PATH_SIZE);
+ msgpack_pack_str(packer, flb_sds_len(ctx->oci_la_log_path));
+ msgpack_pack_str_body(packer, ctx->oci_la_log_path,
+ flb_sds_len(ctx->oci_la_log_path));
+ }
+
+
+ /* Add metadata */
+ if (num_event_meta > 0) {
+ /*
+ "metadata":{
+ "Error ID":"0",
+ "Environment":"dev",
+ "Client Host Region":"IST"
+ },
+ */
+ msgpack_pack_str(packer, FLB_OCI_LOG_METADATA_SIZE);
+ msgpack_pack_str_body(packer, FLB_OCI_LOG_METADATA,
+ FLB_OCI_LOG_METADATA_SIZE);
+
+ msgpack_pack_map(packer, num_event_meta);
+ /* pack kv list */
+ mk_list_foreach(head, &ctx->log_event_metadata_fields) {
+ f = mk_list_entry(head, struct metadata_obj, _head);
+
+ msgpack_pack_str(packer, flb_sds_len(f->key));
+ msgpack_pack_str_body(packer, f->key, flb_sds_len(f->key));
+
+ msgpack_pack_str(packer, flb_sds_len(f->val));
+ msgpack_pack_str_body(packer, f->val, flb_sds_len(f->val));
+
+ }
+
+ }
+}
+
+static int get_and_pack_oci_fields_from_record(msgpack_packer *packer,
+ msgpack_object map,
+ flb_sds_t *lg_id,
+ flb_sds_t *ls_id,
+ struct flb_oci_logan *ctx)
+{
+ int map_size = map.via.map.size;
+ int pck_size = 1, i;
+ msgpack_object *log_group_id= NULL;
+ msgpack_object *log_set_id = NULL;
+ msgpack_object *entity_id = NULL;
+ msgpack_object *entity_type = NULL;
+ msgpack_object *log_path = NULL;
+ msgpack_object *log_source = NULL;
+ msgpack_object *global_metadata = NULL;
+ msgpack_object *metadata = NULL;
+
+ for(i = 0; i < map_size; i++) {
+ if (check_config_from_record(map.via.map.ptr[i].key,
+ FLB_OCI_LOG_GROUP_ID_KEY,
+ FLB_OCI_LOG_GROUP_ID_KEY_SIZE) == FLB_TRUE) {
+ if (map.via.map.ptr[i].val.type == MSGPACK_OBJECT_STR) {
+ log_group_id = &map.via.map.ptr[i].val;
+ }
+ continue;
+ }
+ else if (check_config_from_record(map.via.map.ptr[i].key,
+ FLB_OCI_LOG_SET_ID_KEY,
+ FLB_OCI_LOG_SET_ID_KEY_SIZE) == FLB_TRUE) {
+ if (map.via.map.ptr[i].val.type == MSGPACK_OBJECT_STR) {
+ log_set_id = &map.via.map.ptr[i].val;
+ }
+ continue;
+ }
+ else if (check_config_from_record(map.via.map.ptr[i].key,
+ FLB_OCI_LOG_ENTITY_ID_KEY,
+ FLB_OCI_LOG_ENTITY_ID_KEY_SIZE) == FLB_TRUE) {
+ if (map.via.map.ptr[i].val.type == MSGPACK_OBJECT_STR) {
+ entity_id = &map.via.map.ptr[i].val;
+ pck_size++;
+ }
+ continue;
+ }
+ else if (check_config_from_record(map.via.map.ptr[i].key,
+ FLB_OCI_LOG_ENTITY_TYPE_KEY,
+ FLB_OCI_LOG_ENTITY_TYPE_KEY_SIZE) == FLB_TRUE) {
+ if (map.via.map.ptr[i].val.type == MSGPACK_OBJECT_STR) {
+ entity_type = &map.via.map.ptr[i].val;
+ pck_size++;
+ }
+ continue;
+ }
+ else if (check_config_from_record(map.via.map.ptr[i].key,
+ FLB_OCI_LOG_SOURCE_NAME_KEY,
+ FLB_OCI_LOG_SOURCE_NAME_KEY_SIZE) == FLB_TRUE) {
+ if (map.via.map.ptr[i].val.type == MSGPACK_OBJECT_STR) {
+ log_source = &map.via.map.ptr[i].val;
+ pck_size++;
+ }
+ continue;
+ }
+ else if (check_config_from_record(map.via.map.ptr[i].key,
+ FLB_OCI_LOG_PATH_KEY,
+ FLB_OCI_LOG_PATH_KEY_SIZE) == FLB_TRUE) {
+ if (map.via.map.ptr[i].val.type == MSGPACK_OBJECT_STR) {
+ log_path = &map.via.map.ptr[i].val;
+ pck_size++;
+ }
+ continue;
+ }
+ else if (check_config_from_record(map.via.map.ptr[i].key,
+ FLB_OCI_METADATA_KEY,
+ FLB_OCI_METADATA_KEY_SIZE) == FLB_TRUE) {
+ if (map.via.map.ptr[i].val.type == MSGPACK_OBJECT_STR) {
+ metadata = &map.via.map.ptr[i].val;
+ pck_size++;
+ }
+ continue;
+ }
+ else if (check_config_from_record(map.via.map.ptr[i].key,
+ FLB_OCI_GLOBAL_METADATA_KEY,
+ FLB_OCI_GLOBAL_METADATA_KEY_SIZE) == FLB_TRUE) {
+ if (map.via.map.ptr[i].val.type == MSGPACK_OBJECT_STR) {
+ global_metadata = &map.via.map.ptr[i].val;
+ }
+ continue;
+ }
+ }
+
+ if (log_group_id == NULL || log_source == NULL) {
+ flb_plg_error(ctx->ins,
+ "log source name and log group id are required");
+ return -1;
+ }
+ if (global_metadata != NULL) {
+ msgpack_pack_map(packer, 2);
+ msgpack_pack_str(packer, FLB_OCI_LOG_METADATA_SIZE);
+ msgpack_pack_str_body(packer, FLB_OCI_LOG_METADATA,
+ FLB_OCI_LOG_METADATA_SIZE);
+
+ msgpack_pack_object(packer, *global_metadata);
+ }
+ else {
+ msgpack_pack_map(packer, 1);
+ }
+
+ /*
+ *logEvents":[
+ {
+ "entityId":"",
+ "logSourceName":"LinuxSyslogSource",
+ "logPath":"/var/log/messages",
+ "metadata":{
+ "Error ID":"1",
+ "Environment":"prod",
+ "Client Host Region":"PST"
+ },
+ "logRecords":[
+ "May 8 2017 04:02:36 blr00akm syslogd 1.4.1: shutdown.",
+ "May 8 2017 04:02:37 blr00akm syslogd 1.4.1: restart."
+ ]
+ },
+ {
+
+ }
+ ]
+ */
+ msgpack_pack_str(packer, FLB_OCI_LOG_EVENTS_SIZE);
+ msgpack_pack_str_body(packer, FLB_OCI_LOG_EVENTS, FLB_OCI_LOG_EVENTS_SIZE);
+
+ msgpack_pack_array(packer, 1);
+
+ if (metadata != NULL) {
+ pck_size++;
+ msgpack_pack_map(packer, pck_size); /* entityType, entityId, logSourceName, logPath, metadata, logRecords */
+ msgpack_pack_str(packer, FLB_OCI_LOG_METADATA_SIZE);
+ msgpack_pack_str_body(packer, FLB_OCI_LOG_METADATA,
+ FLB_OCI_LOG_METADATA_SIZE);
+ msgpack_pack_object(packer, *global_metadata);
+
+ }
+ else {
+ msgpack_pack_map(packer, pck_size); /* entityType, entityId, logSourceName, logPath, logRecords */
+ }
+
+ /* "entityType:"" */
+ if (entity_type) {
+ msgpack_pack_str(packer, FLB_OCI_ENTITY_TYPE_SIZE);
+ msgpack_pack_str_body(packer, FLB_OCI_ENTITY_TYPE, FLB_OCI_ENTITY_TYPE_SIZE);
+ msgpack_pack_object(packer, *entity_type);
+ }
+
+ /* "entityId":"", */
+ if (entity_type) {
+ msgpack_pack_str(packer, FLB_OCI_ENTITY_ID_SIZE);
+ msgpack_pack_str_body(packer, FLB_OCI_ENTITY_ID, FLB_OCI_ENTITY_ID_SIZE);
+ msgpack_pack_object(packer, *entity_id);
+ }
+
+
+
+ /* "logSourceName":"", */
+ msgpack_pack_str(packer, FLB_OCI_LOG_SOURCE_NAME_SIZE);
+ msgpack_pack_str_body(packer, FLB_OCI_LOG_SOURCE_NAME,
+ FLB_OCI_LOG_SOURCE_NAME_SIZE);
+ msgpack_pack_object(packer, *log_source);
+
+
+ /* "logPath":"" */
+ if (log_path) {
+ msgpack_pack_str(packer, FLB_OCI_LOG_PATH_SIZE);
+ msgpack_pack_str_body(packer, FLB_OCI_LOG_PATH, FLB_OCI_LOG_PATH_SIZE);
+ msgpack_pack_object(packer, *log_path);
+ }
+
+ *lg_id = flb_sds_create_len(log_group_id->via.str.ptr, log_group_id->via.str.size);
+ if(!*lg_id) {
+ return -1;
+ }
+ if (log_set_id != NULL) {
+ *ls_id = flb_sds_create_len(log_set_id->via.str.ptr, log_set_id->via.str.size);
+ if(!*ls_id) {
+ return -1;
+ }
+ }
+ return 0;
+
+}
+
+static int total_flush(struct flb_event_chunk *event_chunk,
+ struct flb_output_flush *out_flush,
+ struct flb_input_instance *ins, void *out_context,
+ struct flb_config *config)
+{
+ struct flb_oci_logan *ctx = out_context;
+ flb_sds_t out_buf = NULL;
+ int ret = 0, res = FLB_OK, ret1 = 0, i;
+ msgpack_object map;
+ int map_size;
+ msgpack_sbuffer mp_sbuf;
+ msgpack_packer mp_pck;
+ int msg = -1, log = -1;
+ struct flb_log_event_decoder log_decoder;
+ struct flb_log_event log_event;
+ int num_records;
+ flb_sds_t log_group_id = NULL;
+ flb_sds_t log_set_id = NULL;
+ int count = 0;
+
+ ret = flb_log_event_decoder_init(&log_decoder, (char *) event_chunk->data, event_chunk->size);
+
+ if (ret != FLB_EVENT_DECODER_SUCCESS) {
+ flb_plg_error(ctx->ins,
+ "Log event decoder initialization error : %d", ret);
+ res = FLB_ERROR;
+ goto clean_up;
+ }
+
+ /* Create temporary msgpack buffer */
+ msgpack_sbuffer_init(&mp_sbuf);
+ msgpack_packer_init(&mp_pck, &mp_sbuf, msgpack_sbuffer_write);
+
+ /* pack oci fields */
+ /* pack_oci_fields(&mp_pck, ctx); */
+
+ num_records = flb_mp_count(event_chunk->data, event_chunk->size);
+
+ while ((ret = flb_log_event_decoder_next(
+ &log_decoder,
+ &log_event)) == FLB_EVENT_DECODER_SUCCESS) {
+ map = *log_event.body;
+ map_size = map.via.map.size;
+ if (count < 1) {
+ if (ctx->oci_config_in_record == FLB_FALSE) {
+ pack_oci_fields(&mp_pck, ctx);
+ log_group_id = ctx->oci_la_log_group_id;
+ log_set_id = ctx->oci_la_log_set_id;
+ } else {
+ ret1 = get_and_pack_oci_fields_from_record(&mp_pck, map, &log_group_id, &log_set_id, ctx);
+ if (ret1 != 0) {
+ break;
+ }
+ }
+ msgpack_pack_str(&mp_pck, FLB_OCI_LOG_RECORDS_SIZE);
+ msgpack_pack_str_body(&mp_pck, FLB_OCI_LOG_RECORDS,
+ FLB_OCI_LOG_RECORDS_SIZE);
+ msgpack_pack_array(&mp_pck, num_records);
+ count++;
+ }
+
+ for(i = 0; i < map_size; i++) {
+ if (check_config_from_record(map.via.map.ptr[i].key,
+ "message",
+ 7) == FLB_TRUE) {
+ msg = i;
+ }
+ if (check_config_from_record(map.via.map.ptr[i].key,
+ "log",
+ 3) == FLB_TRUE) {
+ log = i;
+ }
+ }
+ if (log >= 0) {
+ msgpack_pack_str(&mp_pck, map.via.map.ptr[log].val.via.str.size);
+ msgpack_pack_str_body(&mp_pck, map.via.map.ptr[log].val.via.str.ptr,
+ map.via.map.ptr[log].val.via.str.size);
+ }
+ else if (msg >= 0) {
+ msgpack_pack_str(&mp_pck, map.via.map.ptr[msg].val.via.str.size);
+ msgpack_pack_str_body(&mp_pck, map.via.map.ptr[msg].val.via.str.ptr,
+ map.via.map.ptr[msg].val.via.str.size);
+ }
+ log = -1;
+ msg = -1;
+ }
+
+ if (ret1 != 0) {
+ res = FLB_ERROR;
+ msgpack_sbuffer_destroy(&mp_sbuf);
+ flb_log_event_decoder_destroy(&log_decoder);
+ goto clean_up;
+ }
+
+ out_buf = flb_msgpack_raw_to_json_sds(mp_sbuf.data, mp_sbuf.size);
+ msgpack_sbuffer_destroy(&mp_sbuf);
+ flb_log_event_decoder_destroy(&log_decoder);
+
+ flb_plg_debug(ctx->ins, "payload=%s", out_buf);
+ flb_plg_debug(ctx->ins, "lg_id=%s", log_group_id);
+
+ ret = flush_to_endpoint(ctx, out_buf, log_group_id, log_set_id);
+ if(ret != FLB_OK) {
+ res = FLB_RETRY;
+ goto clean_up;
+ }
+
+ clean_up:
+ if (out_buf != NULL) {
+ flb_sds_destroy(out_buf);
+ }
+ if (log_group_id != NULL && ctx->oci_config_in_record) {
+ flb_sds_destroy(log_group_id);
+ }
+ if (log_set_id != NULL && ctx->oci_config_in_record) {
+ flb_sds_destroy(log_set_id);
+ }
+ return res;
+}
+
+static void cb_oci_logan_flush(struct flb_event_chunk *event_chunk,
+ struct flb_output_flush *out_flush,
+ struct flb_input_instance *ins, void *out_context,
+ struct flb_config *config)
+{
+ struct flb_oci_logan *ctx = out_context;
+ int ret = -1;
+
+ ret = total_flush(event_chunk, out_flush,
+ ins, out_context,
+ config);
+ if (ret != FLB_OK) {
+ flb_oci_logan_conf_destroy(ctx);
+ FLB_OUTPUT_RETURN(ret);
+ }
+ flb_plg_debug(ctx->ins, "success");
+
+ FLB_OUTPUT_RETURN(FLB_OK);
+
+}
+
+static int cb_oci_logan_exit(void *data, struct flb_config *config)
+{
+ struct flb_oci_logan *ctx = data;
+
+ flb_oci_logan_conf_destroy(ctx);
+ return 0;
+}
+
+/* Configuration properties map */
+static struct flb_config_map config_map[] = {
+ {
+ FLB_CONFIG_MAP_STR, "config_file_location", "",
+ 0, FLB_TRUE, offsetof(struct flb_oci_logan, config_file_location),
+ "Location of the oci config file for user api key signing"
+ },
+ {
+ FLB_CONFIG_MAP_STR, "profile_name", "DEFAULT",
+ 0, FLB_TRUE, offsetof(struct flb_oci_logan, profile_name),
+ "name of the profile in the config file from which the user configs should be loaded"
+ },
+ {
+ FLB_CONFIG_MAP_BOOL, "oci_config_in_record", "false",
+ 0, FLB_TRUE, offsetof(struct flb_oci_logan, oci_config_in_record),
+ "If true, oci_la_* configs will be read from the record"
+ },
+ {
+ FLB_CONFIG_MAP_STR, "uri", NULL,
+ 0, FLB_TRUE, offsetof(struct flb_oci_logan, uri),
+ "Set the uri for rest api request"
+ },
+ {
+ FLB_CONFIG_MAP_STR, "oci_la_log_group_id", NULL,
+ 0, FLB_TRUE, offsetof(struct flb_oci_logan, oci_la_log_group_id),
+ "log group id"
+ },
+ {
+ FLB_CONFIG_MAP_STR, "oci_la_log_set_id", NULL,
+ 0, FLB_TRUE, offsetof(struct flb_oci_logan, oci_la_log_set_id),
+ ""
+ },
+ {
+ FLB_CONFIG_MAP_STR, "oci_la_entity_id", NULL,
+ 0, FLB_TRUE, offsetof(struct flb_oci_logan, oci_la_entity_id),
+ ""
+ },
+ {
+ FLB_CONFIG_MAP_STR, "oci_la_entity_type", NULL,
+ 0, FLB_TRUE, offsetof(struct flb_oci_logan, oci_la_entity_type),
+ ""
+ },
+ {
+ FLB_CONFIG_MAP_STR, "oci_la_log_source_name", NULL,
+ 0, FLB_TRUE, offsetof(struct flb_oci_logan, oci_la_log_source_name),
+ ""
+ },
+ {
+ FLB_CONFIG_MAP_STR, "oci_la_log_set_id", NULL,
+ 0, FLB_TRUE, offsetof(struct flb_oci_logan, oci_la_log_set_id),
+ ""
+ },
+ {
+ FLB_CONFIG_MAP_STR, "oci_la_log_path", NULL,
+ 0, FLB_TRUE, offsetof(struct flb_oci_logan, oci_la_log_path),
+ ""
+ },
+ {
+ FLB_CONFIG_MAP_SLIST_2, "oci_la_global_metadata", NULL,
+ FLB_CONFIG_MAP_MULT, FLB_TRUE, offsetof(struct flb_oci_logan, oci_la_global_metadata),
+ ""
+ },
+ {
+ FLB_CONFIG_MAP_SLIST_2, "oci_la_metadata", NULL,
+ FLB_CONFIG_MAP_MULT, FLB_TRUE, offsetof(struct flb_oci_logan, oci_la_metadata),
+ ""
+ },
+ {
+ FLB_CONFIG_MAP_STR, "namespace", NULL,
+ 0, FLB_TRUE, offsetof(struct flb_oci_logan, namespace),
+ "namespace in your tenancy where the log objects reside"
+ },
+ {
+ FLB_CONFIG_MAP_STR, "proxy", NULL,
+ 0, FLB_TRUE, offsetof(struct flb_oci_logan, proxy),
+ "define proxy if required, in http://host:port format, supports only http protocol"
+ },
+
+ {0}
+};
+
+/* Plugin reference */
+struct flb_output_plugin out_oracle_log_analytics_plugin = {
+ .name = "oracle_log_analytics",
+ .description = "Oracle log analytics",
+ .cb_init = cb_oci_logan_init,
+ .cb_pre_run = NULL,
+ .cb_flush = cb_oci_logan_flush,
+ .cb_exit = cb_oci_logan_exit,
+
+ /* Configuration */
+ .config_map = config_map,
+
+ /* Events supported */
+ .event_type = FLB_OUTPUT_LOGS,
+
+
+ /* Plugin flags */
+ .flags = FLB_OUTPUT_NET | FLB_IO_OPT_TLS,
+ .workers = 1,
+};
diff --git a/src/fluent-bit/plugins/out_oracle_log_analytics/oci_logan.h b/src/fluent-bit/plugins/out_oracle_log_analytics/oci_logan.h
new file mode 100644
index 000000000..7cc9e75f4
--- /dev/null
+++ b/src/fluent-bit/plugins/out_oracle_log_analytics/oci_logan.h
@@ -0,0 +1,215 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+
+/* Fluent Bit
+ * ==========
+ * Copyright (C) 2015-2023 The Fluent Bit Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#ifndef FLB_OUT_OCI_LOGAN_H
+#define FLB_OUT_OCI_LOGAN_H
+
+#define FLB_OCI_LOG_ENTITY_ID_KEY "oci_la_entity_id"
+#define FLB_OCI_LOG_ENTITY_ID_KEY_SIZE sizeof(FLB_OCI_LOG_ENTITY_ID_KEY) - 1
+
+#define FLB_OCI_LOG_ENTITY_TYPE_KEY "oci_la_entity_type"
+#define FLB_OCI_LOG_ENTITY_TYPE_KEY_SIZE sizeof(FLB_OCI_LOG_ENTITY_TYPE_KEY) - 1
+
+#define FLB_OCI_LOG_GROUP_ID_KEY "oci_la_log_group_id"
+#define FLB_OCI_LOG_GROUP_ID_KEY_SIZE sizeof(FLB_OCI_LOG_GROUP_ID_KEY) - 1
+
+#define FLB_OCI_LOG_SET_ID_KEY "oci_la_log_set_id"
+#define FLB_OCI_LOG_SET_ID_KEY_SIZE sizeof(FLB_OCI_LOG_SET_ID_KEY) - 1
+
+#define FLB_OCI_LOG_SOURCE_NAME_KEY "oci_la_log_source_name"
+#define FLB_OCI_LOG_SOURCE_NAME_KEY_SIZE sizeof(FLB_OCI_LOG_SOURCE_NAME_KEY) - 1
+
+#define FLB_OCI_LOG_PATH_KEY "oci_la_log_path"
+#define FLB_OCI_LOG_PATH_KEY_SIZE sizeof(FLB_OCI_LOG_PATH_KEY) - 1
+
+#define FLB_OCI_METADATA_KEY "oci_la_metadata"
+#define FLB_OCI_METADATA_KEY_SIZE sizeof(FLB_OCI_METADATA_KEY) - 1
+
+#define FLB_OCI_GLOBAL_METADATA_KEY "oci_la_global_metadata"
+#define FLB_OCI_GLOBAL_METADATA_KEY_SIZE sizeof(FLB_OCI_GLOBAL_METADATA_KEY) - 1
+
+#define FLB_OCI_LOG_EVENTS "logEvents"
+#define FLB_OCI_LOG_EVENTS_SIZE sizeof(FLB_OCI_LOG_EVENTS)-1
+
+#define FLB_OCI_LOG_RECORDS "logRecords"
+#define FLB_OCI_LOG_RECORDS_SIZE sizeof(FLB_OCI_LOG_RECORDS)-1
+
+#define FLB_OCI_LOG_GROUP_ID "logGroupId"
+#define FLB_OCI_LOG_GROUP_ID_SIZE sizeof(FLB_OCI_LOG_GROUP_ID)-1
+
+#define FLB_OCI_ENTITY_TYPE "entityType"
+#define FLB_OCI_ENTITY_TYPE_SIZE sizeof(FLB_OCI_ENTITY_TYPE) - 1
+
+#define FLB_OCI_LOG_SET "logSet"
+#define FLB_OCI_LOG_SET_SIZE sizeof(FLB_OCI_LOG_SET)-1
+
+#define FLB_OCI_LOG_METADATA "metadata"
+#define FLB_OCI_LOG_METADATA_SIZE sizeof(FLB_OCI_LOG_METADATA)-1
+
+#define FLB_OCI_ENTITY_ID "entityId"
+#define FLB_OCI_ENTITY_ID_SIZE sizeof(FLB_OCI_ENTITY_ID)-1
+
+#define FLB_OCI_LOG_SOURCE_NAME "logSourceName"
+#define FLB_OCI_LOG_SOURCE_NAME_SIZE sizeof(FLB_OCI_LOG_SOURCE_NAME)-1
+
+#define FLB_OCI_LOG_PATH "logPath"
+#define FLB_OCI_LOG_PATH_SIZE sizeof(FLB_OCI_LOG_PATH)-1
+
+#define FLB_OCI_META_PREFIX "metadata_"
+#define FLB_OCI_META_PREFIX_SIZE sizeof(FLB_OCI_META_PREFIX)-1
+
+#define FLB_OCI_MATCH_PREFIX "oci_match_"
+#define FLB_OCI_MATCH_PREFIX_SIZE sizeof(FLB_OCI_MATCH_PREFIX)-1
+
+#ifdef FLB_HAVE_REGEX
+#define FLB_OCI_MATCH_REGEX_PREFIX "oci_match_regex_"
+#define FLB_OCI_MATCH_REGEX_PREFIX_SIZE sizeof(FLB_OCI_MATCH_REGEX_PREFIX)-1
+#endif
+
+/* Params */
+#define FLB_OCI_PARAM_SKIP_HTTP_POST "skip_http_post"
+#define FLB_OCI_PARAM_URI "uri"
+#define FLB_OCI_PARAM_ENABLE_TRACE_OUTPUT "enable_trace"
+#define FLB_OCI_PARAM_TRACE_OUTPUT_PATH "trace_file_path"
+#define FLB_OCI_PARAM_TRACE_OUTPUT_FILE "trace_file_name"
+#define FLB_OCI_PARAM_COLLECT_TIME_FIELD "collect_time_field_name"
+
+#define FLB_OCI_PARAM_USE_RAW_RECORD "use_raw_record"
+#define FLB_OCI_PARAM_USE_RAW_RECORD_SIZE sizeof(FLB_OCI_PARAM_USE_RAW_RECORD)-1
+
+#define FLB_OCI_PARAM_INCLUDE_COLLECT_TIME "include_collect_time"
+#define FLB_OCI_PARAM_INCLUDE_COLLECT_TIME_SIZE sizeof(FLB_OCI_PARAM_INCLUDE_COLLECT_TIME)-1
+
+#define FLB_OCI_MATCH_ID_MAX 1000 // TO avoid too large memory allocation
+
+#define FLB_OCI_DEFAULT_COLLECT_TIME "oci_collect_time"
+#define FLB_OCI_DEFAULT_COLLECT_TIME_SIZE sizeof(FLB_OCI_DEFAULT_COLLECT_TIME)-1
+
+/* Http Header */
+#define FLB_OCI_HEADER_REQUEST_TARGET "(request-target)"
+#define FLB_OCI_HEADER_USER_AGENT "User-Agent"
+#define FLB_OCI_HEADER_USER_AGENT_VAL "Fluent-Bit"
+#define FLB_OCI_HEADER_CONTENT_TYPE "content-type"
+#define FLB_OCI_HEADER_CONTENT_TYPE_VAL "application/octet-stream"
+#define FLB_OCI_HEADER_X_CONTENT_SHA256 "x-content-sha256"
+#define FLB_OCI_HEADER_CONTENT_LENGTH "content-length"
+#define FLB_OCI_HEADER_HOST "host"
+#define FLB_OCI_HEADER_DATE "date"
+#define FLB_OCI_HEADER_AUTH "Authorization"
+#define FLB_OCI_PAYLOAD_TYPE "payloadType"
+
+
+/* For OCI signing */
+#define FLB_OCI_PARAM_TENANCY "tenancy"
+#define FLB_OCI_PARAM_USER "user"
+#define FLB_OCI_PARAM_KEY_FINGERPRINT "fingerprint"
+#define FLB_OCI_PARAM_KEY_FILE "key_file"
+#define FLB_OCI_PARAM_REGION "region"
+#define FLB_OCI_PARAM_KEY_FILE_PASSPHRASE "key_file_passphrase"
+
+#define FLB_OCI_SIGN_SIGNATURE_VERSION "Signature version=\"1\""
+#define FLB_OCI_SIGN_KEYID "keyId"
+#define FLB_OCI_SIGN_ALGORITHM "algorithm=\"rsa-sha256\""
+
+#define FLB_OCI_SIGN_HEADERS "headers=\"" \
+ FLB_OCI_HEADER_REQUEST_TARGET " " \
+ FLB_OCI_HEADER_HOST " " \
+ FLB_OCI_HEADER_DATE " " \
+ FLB_OCI_HEADER_X_CONTENT_SHA256 " " \
+ FLB_OCI_HEADER_CONTENT_TYPE " " \
+ FLB_OCI_HEADER_CONTENT_LENGTH "\""
+
+#define FLB_OCI_SIGN_SIGNATURE "signature"
+
+/* For error response */
+#define FLB_OCI_ERROR_RESPONSE_CODE "code"
+#define FLB_OCI_ERROR_RESPONSE_MESSAGE "message"
+
+#define FLB_OCI_ERROR_CODE_RELATED_RESOURCE_NOT_FOUND "RelatedResourceNotAuthorizedOrNotFound"
+#define FLB_OCI_ERROR_CODE_NOT_AUTHENTICATED "NotAuthenticated"
+#define FLB_OCI_ERROR_CODE_NOT_AUTHENTICATEDORNOTFOUND "NotAuthorizedOrNotFound"
+#define FLB_OCI_ERROR_CODE_INCORRECTSTATE "IncorrectState"
+#define FLB_OCI_ERROR_CODE_NOT_AUTH_OR_RESOURCE_EXIST "NotAuthorizedOrResourceAlreadyExists"
+#define FLB_OCI_ERROR_CODE_TOO_MANY_REQUESTS "TooManyRequests"
+#define FLB_OCI_ERROR_CODE_INTERNAL_SERVER_ERROR "InternalServerError"
+
+#include <fluent-bit/flb_upstream.h>
+#include <fluent-bit/flb_sds.h>
+#include <fluent-bit/flb_record_accessor.h>
+#include <fluent-bit/flb_hash_table.h>
+#include <monkey/mk_core/mk_list.h>
+
+struct metadata_obj {
+ flb_sds_t key;
+ flb_sds_t val;
+ struct mk_list _head;
+
+};
+
+struct flb_oci_error_response
+{
+ flb_sds_t code;
+ flb_sds_t message;
+};
+
+struct flb_oci_logan {
+ flb_sds_t namespace;
+ flb_sds_t config_file_location;
+ flb_sds_t profile_name;
+ int oci_config_in_record;
+ flb_sds_t uri;
+
+ struct flb_upstream *u;
+ flb_sds_t proxy;
+ char *proxy_host;
+ int proxy_port;
+
+ // oci_la_* configs
+ flb_sds_t oci_la_entity_id;
+
+ flb_sds_t oci_la_entity_type;
+
+ flb_sds_t oci_la_log_source_name;
+
+ flb_sds_t oci_la_log_path;
+
+ flb_sds_t oci_la_log_group_id;
+
+ flb_sds_t oci_la_log_set_id;
+
+ struct mk_list *oci_la_global_metadata;
+ struct mk_list global_metadata_fields;
+ struct mk_list *oci_la_metadata;
+ struct mk_list log_event_metadata_fields;
+
+ // config_file
+ flb_sds_t user;
+ flb_sds_t region;
+ flb_sds_t tenancy;
+ flb_sds_t key_fingerprint;
+ flb_sds_t key_file;
+ /* For OCI signing */
+ flb_sds_t key_id; // tenancy/user/key_fingerprint
+ flb_sds_t private_key;
+
+ struct flb_output_instance *ins;
+
+};
+#endif
diff --git a/src/fluent-bit/plugins/out_oracle_log_analytics/oci_logan_conf.c b/src/fluent-bit/plugins/out_oracle_log_analytics/oci_logan_conf.c
new file mode 100644
index 000000000..a39803184
--- /dev/null
+++ b/src/fluent-bit/plugins/out_oracle_log_analytics/oci_logan_conf.c
@@ -0,0 +1,493 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+
+/* Fluent Bit
+ * ==========
+ * Copyright (C) 2015-2023 The Fluent Bit Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#include <sys/stat.h>
+#include <fluent-bit/flb_info.h>
+#include <fluent-bit/flb_output.h>
+#include <fluent-bit/flb_output_plugin.h>
+#include <fluent-bit/flb_config.h>
+#include <fluent-bit/flb_error.h>
+#include <fluent-bit/flb_record_accessor.h>
+#include <fluent-bit/flb_config_map.h>
+#include <fluent-bit/flb_slist.h>
+#include <fluent-bit/flb_file.h>
+
+#include <monkey/mk_core/mk_list.h>
+#include <monkey/mk_core/mk_string.h>
+#include <fluent-bit/flb_utils.h>
+
+#include "oci_logan.h"
+#include "oci_logan_conf.h"
+
+static int create_pk_context(flb_sds_t filepath, const char *key_passphrase,
+ struct flb_oci_logan *ctx)
+{
+ int ret;
+ struct stat st;
+ struct file_info finfo;
+ FILE *fp;
+ flb_sds_t kbuffer;
+
+
+ ret = stat(filepath, &st);
+ if (ret == -1) {
+ flb_errno();
+ flb_plg_error(ctx->ins, "cannot open key file %s", filepath);
+ return -1;
+ }
+
+ if (!S_ISREG(st.st_mode) && !S_ISLNK(st.st_mode)) {
+ flb_plg_error(ctx->ins, "key file is not a valid file: %s", filepath);
+ return -1;
+ }
+
+ /* Read file content */
+ if (mk_file_get_info(filepath, &finfo, MK_FILE_READ) != 0) {
+ flb_plg_error(ctx->ins, "error to read key file: %s", filepath);
+ return -1;
+ }
+
+ if (!(fp = fopen(filepath, "rb"))) {
+ flb_plg_error(ctx->ins, "error to open key file: %s", filepath);
+ return -1;
+ }
+
+ kbuffer = flb_sds_create_size(finfo.size + 1);
+ if (!kbuffer) {
+ flb_errno();
+ fclose(fp);
+ return -1;
+ }
+
+ ret = fread(kbuffer, finfo.size, 1, fp);
+ if (ret < 1) {
+ flb_sds_destroy(kbuffer);
+ fclose(fp);
+ flb_plg_error(ctx->ins, "fail to read key file: %s", filepath);
+ return -1;
+ }
+ fclose(fp);
+
+ /* In mbedtls, for PEM, the buffer must contains a null-terminated string */
+ kbuffer[finfo.size] = '\0';
+ flb_sds_len_set(kbuffer, finfo.size + 1);
+
+ ctx->private_key = kbuffer;
+
+ return 0;
+}
+
+static int load_oci_credentials(struct flb_oci_logan *ctx)
+{
+ flb_sds_t content;
+ int found_profile = 0, res = 0;
+ char *line, *profile = NULL;
+ int eq_pos = 0;
+ char* key = NULL;
+ char* val;
+
+ content = flb_file_read(ctx->config_file_location);
+ if (content == NULL || flb_sds_len(content) == 0)
+ {
+ return -1;
+ }
+ flb_plg_debug(ctx->ins, "content = %s", content);
+ line = strtok(content, "\n");
+ while(line != NULL) {
+ /* process line */
+ flb_plg_debug(ctx->ins, "line = %s", line);
+ if(!found_profile && line[0] == '[') {
+ profile = mk_string_copy_substr(line, 1, strlen(line) - 1);
+ if(!strcmp(profile, ctx->profile_name)) {
+ flb_plg_info(ctx->ins, "found profile");
+ found_profile = 1;
+ goto iterate;
+ }
+ mk_mem_free(profile);
+ }
+ if(found_profile) {
+ if(line[0] == '[') {
+ break;
+ }
+ eq_pos = mk_string_char_search(line, '=', strlen(line));
+ flb_plg_debug(ctx->ins, "eq_pos %d", eq_pos);
+ key = mk_string_copy_substr(line, 0, eq_pos);
+ flb_plg_debug(ctx->ins, "key = %s", key);
+ val = line + eq_pos + 1;
+ if (!key || !val) {
+ res = -1;
+ break;
+ }
+ if (strcmp(key, FLB_OCI_PARAM_USER) == 0) {
+ ctx->user = flb_sds_create(val);
+ }
+ else if (strcmp(key, FLB_OCI_PARAM_TENANCY) == 0) {
+ ctx->tenancy = flb_sds_create(val);
+ }
+ else if (strcmp(key, FLB_OCI_PARAM_KEY_FILE) == 0) {
+ ctx->key_file = flb_sds_create(val);
+ }
+ else if (strcmp(key, FLB_OCI_PARAM_KEY_FINGERPRINT) == 0) {
+ ctx->key_fingerprint = flb_sds_create(val);
+ }
+ else if (strcmp(key, FLB_OCI_PARAM_REGION) == 0) {
+ ctx->region = flb_sds_create(val);
+ }
+ else {
+ goto iterate;
+ }
+ }
+ iterate:
+ if (profile) {
+ mk_mem_free(profile);
+ profile = NULL;
+ }
+ if (key) {
+ mk_mem_free(key);
+ key = NULL;
+ }
+ line = strtok(NULL, "\n");
+ }
+ if (!found_profile) {
+ flb_errno();
+ res = -1;
+ }
+
+ flb_sds_destroy(content);
+ if (profile) {
+ mk_mem_free(profile);
+ }
+ if (key) {
+ mk_mem_free(key);
+ }
+ return res;
+}
+
+static int global_metadata_fields_create(struct flb_oci_logan *ctx)
+{
+ struct mk_list *head;
+ struct flb_slist_entry *kname;
+ struct flb_slist_entry *val;
+ struct flb_config_map_val *mv;
+ struct metadata_obj *f;
+
+ if (!ctx->oci_la_global_metadata) {
+ return 0;
+ }
+
+ flb_config_map_foreach(head, mv, ctx->oci_la_global_metadata) {
+ kname = mk_list_entry_first(mv->val.list, struct flb_slist_entry, _head);
+ val = mk_list_entry_last(mv->val.list, struct flb_slist_entry, _head);
+
+ f = flb_malloc(sizeof(struct metadata_obj));
+ if (!f) {
+ flb_errno();
+ return -1;
+ }
+
+ f->key = flb_sds_create(kname->str);
+ if (!f->key) {
+ flb_free(f);
+ return -1;
+ }
+ f->val = flb_sds_create(val->str);
+ if (!f->val) {
+ flb_free(f);
+ return -1;
+ }
+
+
+ mk_list_add(&f->_head, &ctx->global_metadata_fields);
+ }
+
+ return 0;
+}
+
+static int log_event_metadata_create(struct flb_oci_logan *ctx)
+{
+ struct mk_list *head;
+ struct flb_slist_entry *kname;
+ struct flb_slist_entry *val;
+ struct flb_config_map_val *mv;
+ struct metadata_obj *f;
+
+ if (!ctx->oci_la_metadata) {
+ return 0;
+ }
+
+ flb_config_map_foreach(head, mv, ctx->oci_la_metadata) {
+ kname = mk_list_entry_first(mv->val.list, struct flb_slist_entry, _head);
+ val = mk_list_entry_last(mv->val.list, struct flb_slist_entry, _head);
+
+ f = flb_malloc(sizeof(struct metadata_obj));
+ if (!f) {
+ flb_errno();
+ return -1;
+ }
+
+ f->key = flb_sds_create(kname->str);
+ if (!f->key) {
+ flb_free(f);
+ return -1;
+ }
+ f->val = flb_sds_create(val->str);
+ if (!f->val) {
+ flb_free(f);
+ return -1;
+ }
+
+
+ mk_list_add(&f->_head, &ctx->log_event_metadata_fields);
+ }
+
+ return 0;
+}
+struct flb_oci_logan *flb_oci_logan_conf_create(struct flb_output_instance *ins,
+ struct flb_config *config) {
+ struct flb_oci_logan *ctx;
+ struct flb_upstream *upstream;
+ flb_sds_t host = NULL;
+ int io_flags = 0, default_port;
+ const char *tmp;
+ int ret = 0;
+ char *protocol = NULL;
+ char *p_host = NULL;
+ char *p_port = NULL;
+ char *p_uri = NULL;
+
+ ctx = flb_calloc(1, sizeof(struct flb_oci_logan));
+ if (!ctx) {
+ flb_errno();
+ return NULL;
+ }
+
+ ctx->ins = ins;
+
+ ret = flb_output_config_map_set(ins, (void *) ctx);
+ if (ret == -1) {
+ flb_plg_error(ctx->ins, "configuration error");
+ flb_oci_logan_conf_destroy(ctx);
+ return NULL;
+ }
+
+ if (ctx->oci_config_in_record == FLB_FALSE) {
+ if (ctx->oci_la_log_source_name == NULL ||
+ ctx->oci_la_log_group_id == NULL) {
+ flb_errno();
+ flb_plg_error(ctx->ins,
+ "log source name and log group id are required");
+ flb_oci_logan_conf_destroy(ctx);
+ return NULL;
+ }
+ }
+ if (ctx->oci_la_global_metadata != NULL) {
+ mk_list_init(&ctx->global_metadata_fields);
+ ret = global_metadata_fields_create(ctx);
+ if (ret != 0) {
+ flb_errno();
+ flb_oci_logan_conf_destroy(ctx);
+ return NULL;
+ }
+ }
+
+ if (ctx->oci_la_metadata != NULL) {
+ mk_list_init(&ctx->log_event_metadata_fields);
+ ret = log_event_metadata_create(ctx);
+ if (ret != 0) {
+ flb_errno();
+ flb_oci_logan_conf_destroy(ctx);
+ return NULL;
+ }
+ }
+
+ if (!ctx->config_file_location) {
+ flb_errno();
+ flb_plg_error(ctx->ins, "config file location is required");
+ flb_oci_logan_conf_destroy(ctx);
+ return NULL;
+ }
+
+ ret = load_oci_credentials(ctx);
+ if(ret != 0) {
+ flb_errno();
+ flb_oci_logan_conf_destroy(ctx);
+ return NULL;
+ }
+
+ if (ins->host.name) {
+ host = ins->host.name;
+ }
+ else {
+ if (!ctx->region) {
+ flb_errno();
+ flb_plg_error(ctx->ins, "Region is required");
+ flb_oci_logan_conf_destroy(ctx);
+ return NULL;
+ }
+ host = flb_sds_create_size(512);
+ flb_sds_snprintf(&host, flb_sds_alloc(host), "loganalytics.%s.oci.oraclecloud.com", ctx->region);
+ }
+
+ if (!ctx->uri) {
+ if (!ctx->namespace) {
+ flb_errno();
+ flb_plg_error(ctx->ins, "Namespace is required");
+ flb_oci_logan_conf_destroy(ctx);
+ return NULL;
+ }
+ ctx->uri = flb_sds_create_size(512);
+ flb_sds_snprintf(&ctx->uri, flb_sds_alloc(ctx->uri),
+ "/20200601/namespaces/%s/actions/uploadLogEventsFile",
+ ctx->namespace);
+ }
+
+
+
+ if (create_pk_context(ctx->key_file, NULL, ctx) < 0) {
+ flb_plg_error(ctx->ins, "failed to create pk context");
+ flb_oci_logan_conf_destroy(ctx);
+ return NULL;
+ }
+
+
+ ctx->key_id = flb_sds_create_size(512);
+ flb_sds_snprintf(&ctx->key_id, flb_sds_alloc(ctx->key_id),
+ "%s/%s/%s", ctx->tenancy, ctx->user, ctx->key_fingerprint);
+
+
+ /* Check if SSL/TLS is enabled */
+ io_flags = FLB_IO_TCP;
+ default_port = 80;
+
+#ifdef FLB_HAVE_TLS
+ if (ins->use_tls == FLB_TRUE) {
+ io_flags = FLB_IO_TLS;
+ default_port = 443;
+ }
+#endif
+
+ if (ins->host.ipv6 == FLB_TRUE) {
+ io_flags |= FLB_IO_IPV6;
+ }
+
+ flb_output_net_default(host, default_port, ins);
+ flb_sds_destroy(host);
+
+ if (ctx->proxy) {
+ ret = flb_utils_url_split(tmp, &protocol, &p_host, &p_port, &p_uri);
+ if (ret == -1) {
+ flb_plg_error(ctx->ins, "could not parse proxy parameter: '%s'", tmp);
+ flb_oci_logan_conf_destroy(ctx);
+ return NULL;
+ }
+
+ ctx->proxy_host = p_host;
+ ctx->proxy_port = atoi(p_port);
+ flb_free(protocol);
+ flb_free(p_port);
+ flb_free(p_uri);
+ flb_free(p_host);
+ }
+
+ if (ctx->proxy) {
+ upstream = flb_upstream_create(config, ctx->proxy_host, ctx->proxy_port,
+ io_flags, ins->tls);
+ }
+ else {
+ /* Prepare an upstream handler */
+ upstream = flb_upstream_create(config, ins->host.name, ins->host.port,
+ io_flags, ins->tls);
+ }
+
+ if (!upstream) {
+ flb_plg_error(ctx->ins, "cannot create Upstream context");
+ flb_oci_logan_conf_destroy(ctx);
+ return NULL;
+ }
+ ctx->u = upstream;
+
+ /* Set instance flags into upstream */
+ flb_output_upstream_set(ctx->u, ins);
+
+ return ctx;
+}
+
+static void metadata_fields_destroy(struct flb_oci_logan *ctx)
+{
+ struct mk_list *tmp;
+ struct mk_list *head;
+ struct metadata_obj *f;
+
+ mk_list_foreach_safe(head, tmp, &ctx->global_metadata_fields) {
+ f = mk_list_entry(head, struct metadata_obj, _head);
+ flb_sds_destroy(f->key);
+ flb_sds_destroy(f->val);
+ mk_list_del(&f->_head);
+ flb_free(f);
+ }
+
+ mk_list_foreach_safe(head, tmp, &ctx->log_event_metadata_fields) {
+ f = mk_list_entry(head, struct metadata_obj, _head);
+ flb_sds_destroy(f->key);
+ flb_sds_destroy(f->val);
+ mk_list_del(&f->_head);
+ flb_free(f);
+ }
+
+}
+
+int flb_oci_logan_conf_destroy(struct flb_oci_logan *ctx) {
+ if(ctx == NULL) {
+ return 0;
+ }
+
+ if (ctx->private_key) {
+ flb_sds_destroy(ctx->private_key);
+ }
+ if (ctx->uri) {
+ flb_sds_destroy(ctx->uri);
+ }
+ if (ctx->key_id) {
+ flb_sds_destroy(ctx->key_id);
+ }
+ if (ctx->key_file) {
+ flb_sds_destroy(ctx->key_file);
+ }
+ if(ctx->user) {
+ flb_sds_destroy(ctx->user);
+ }
+ if(ctx->key_fingerprint) {
+ flb_sds_destroy(ctx->key_fingerprint);
+ }
+ if(ctx->tenancy) {
+ flb_sds_destroy(ctx->tenancy);
+ }
+ if(ctx->region) {
+ flb_sds_destroy(ctx->region);
+ }
+ if (ctx->u) {
+ flb_upstream_destroy(ctx->u);
+ }
+
+ metadata_fields_destroy(ctx);
+
+ flb_free(ctx);
+ return 0;
+} \ No newline at end of file
diff --git a/src/fluent-bit/plugins/out_oracle_log_analytics/oci_logan_conf.h b/src/fluent-bit/plugins/out_oracle_log_analytics/oci_logan_conf.h
new file mode 100644
index 000000000..a11832b0a
--- /dev/null
+++ b/src/fluent-bit/plugins/out_oracle_log_analytics/oci_logan_conf.h
@@ -0,0 +1,34 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+
+/* Fluent Bit
+ * ==========
+ * Copyright (C) 2015-2023 The Fluent Bit Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#ifndef FLB_OUT_OCI_LOGAN_CONF_H
+#define FLB_OUT_OCI_LOGAN_CONF_H
+
+#include <fluent-bit/flb_info.h>
+#include <fluent-bit/flb_output.h>
+#include <fluent-bit/flb_config.h>
+
+#include "oci_logan.h"
+
+struct flb_oci_logan *flb_oci_logan_conf_create(struct flb_output_instance *ins,
+ struct flb_config *config);
+int flb_oci_logan_conf_destroy(struct flb_oci_logan *ctx);
+
+#endif