<commit_before>/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */

/*  Fluent Bit
 *  ==========
 *  Copyright (C) 2019      The Fluent Bit Authors
 *  Copyright (C) 2015-2018 Treasure Data Inc.
 *
 *  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_info.h>
#include <fluent-bit/flb_output.h>
#include <fluent-bit/flb_time.h>
#include <fluent-bit/flb_pack.h>

#include "kafka_config.h"
#include "kafka_topic.h"

void cb_kafka_msg(rd_kafka_t *rk, const rd_kafka_message_t *rkmessage,
                  void *opaque)
{
    if (rkmessage->err) {
        flb_warn("[out_kafka] message delivery failed: %s",
                 rd_kafka_err2str(rkmessage->err));
    }
    else {
        flb_debug("[out_kafka] message delivered (%zd bytes, "
                  "partition %"PRId32")",
                  rkmessage->len, rkmessage->partition);
    }
}

void cb_kafka_logger(const rd_kafka_t *rk, int level,
                     const char *fac, const char *buf)
{

    flb_error("[out_kafka] %s: %s",
              rk ? rd_kafka_name(rk) : NULL, buf);
}

static int cb_kafka_init(struct flb_output_instance *ins,
                         struct flb_config *config,
                         void *data)
{
    struct flb_kafka *ctx;

    /* Configuration */
    ctx = flb_kafka_conf_create(ins, config);
    if (!ctx) {
        flb_error("[out_kafka] failed to initialize");
        return -1;
    }

    /* Set global context */
    flb_output_set_context(ins, ctx);
    return 0;
}

int produce_message(struct flb_time *tm, msgpack_object *map,
                    struct flb_kafka *ctx, struct flb_config *config)
{
    int i;
    int ret;
    int size;
    int queue_full_retries = 0;
    char *out_buf;
    size_t out_size;
    struct flb_kafka_topic *topic = NULL;
    msgpack_sbuffer mp_sbuf;
    msgpack_packer mp_pck;
    msgpack_object key;
    msgpack_object val;
    flb_sds_t s;

    /* Init temporal buffers */
    msgpack_sbuffer_init(&mp_sbuf);
    msgpack_packer_init(&mp_pck, &mp_sbuf, msgpack_sbuffer_write);

    if (ctx->format == FLB_KAFKA_FMT_JSON || ctx->format == FLB_KAFKA_FMT_MSGP) {
        /* Make room for the timestamp */
        size = map->via.map.size + 1;
        msgpack_pack_map(&mp_pck, size);

        /* Pack timestamp */
        msgpack_pack_str(&mp_pck, ctx->timestamp_key_len);
        msgpack_pack_str_body(&mp_pck,
                              ctx->timestamp_key, ctx->timestamp_key_len);
        switch (ctx->timestamp_format) {
            case FLB_JSON_DATE_DOUBLE:
                msgpack_pack_double(&mp_pck, flb_time_to_double(tm));
                break;

            case FLB_JSON_DATE_ISO8601:
                {
                size_t date_len;
                int len;
                struct tm _tm;
                char time_formatted[32];
                /* Format the time; use microsecond precision (not nanoseconds). */
                gmtime_r(&tm->tm.tv_sec, &_tm);
                date_len = strftime(time_formatted, sizeof(time_formatted) - 1,
                             FLB_JSON_DATE_ISO8601_FMT, &_tm);

                len = snprintf(time_formatted + date_len, sizeof(time_formatted) - 1 - date_len,
                               ".%06" PRIu64 "Z", (uint64_t) tm->tm.tv_nsec / 1000);
                date_len += len;

                msgpack_pack_str(&mp_pck, date_len);
                msgpack_pack_str_body(&mp_pck, time_formatted, date_len);
                }
                break;
        }
    }
    else {
        size = map->via.map.size;
        msgpack_pack_map(&mp_pck, size);
    }

    for (i = 0; i < map->via.map.size; i++) {
        key = map->via.map.ptr[i].key;
        val = map->via.map.ptr[i].val;

        msgpack_pack_object(&mp_pck, key);
        msgpack_pack_object(&mp_pck, val);

        /* Lookup key/topic */
        if (ctx->topic_key && !topic && val.type == MSGPACK_OBJECT_STR) {
            if (key.via.str.size == ctx->topic_key_len &&
                strncmp(key.via.str.ptr, ctx->topic_key, ctx->topic_key_len) == 0) {
                topic = flb_kafka_topic_lookup(val.via.str.ptr,
                                               val.via.str.size,
                                               ctx);
            }
        }
    }

    if (ctx->format == FLB_KAFKA_FMT_JSON) {
        s = flb_msgpack_raw_to_json_sds(mp_sbuf.data, mp_sbuf.size);
        if (!s) {
            flb_error("[out_kafka] error encoding to JSON");
            msgpack_sbuffer_destroy(&mp_sbuf);
            return FLB_ERROR;
        }
        out_buf  = s;
        out_size = flb_sds_len(out_buf);
    }
    else if (ctx->format == FLB_KAFKA_FMT_MSGP) {
        out_buf = mp_sbuf.data;
        out_size = mp_sbuf.size;
    }
    else if (ctx->format == FLB_KAFKA_FMT_GELF) {
        s = flb_msgpack_raw_to_gelf(mp_sbuf.data, mp_sbuf.size,<commit_msg>out_kafka: add cast to parameter<commit_after>/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */

/*  Fluent Bit
 *  ==========
 *  Copyright (C) 2019      The Fluent Bit Authors
 *  Copyright (C) 2015-2018 Treasure Data Inc.
 *
 *  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_info.h>
#include <fluent-bit/flb_output.h>
#include <fluent-bit/flb_time.h>
#include <fluent-bit/flb_pack.h>

#include "kafka_config.h"
#include "kafka_topic.h"

void cb_kafka_msg(rd_kafka_t *rk, const rd_kafka_message_t *rkmessage,
                  void *opaque)
{
    if (rkmessage->err) {
        flb_warn("[out_kafka] message delivery failed: %s",
                 rd_kafka_err2str(rkmessage->err));
    }
    else {
        flb_debug("[out_kafka] message delivered (%zd bytes, "
                  "partition %"PRId32")",
                  rkmessage->len, rkmessage->partition);
    }
}

void cb_kafka_logger(const rd_kafka_t *rk, int level,
                     const char *fac, const char *buf)
{

    flb_error("[out_kafka] %s: %s",
              rk ? rd_kafka_name(rk) : NULL, buf);
}

static int cb_kafka_init(struct flb_output_instance *ins,
                         struct flb_config *config,
                         void *data)
{
    struct flb_kafka *ctx;

    /* Configuration */
    ctx = flb_kafka_conf_create(ins, config);
    if (!ctx) {
        flb_error("[out_kafka] failed to initialize");
        return -1;
    }

    /* Set global context */
    flb_output_set_context(ins, ctx);
    return 0;
}

int produce_message(struct flb_time *tm, msgpack_object *map,
                    struct flb_kafka *ctx, struct flb_config *config)
{
    int i;
    int ret;
    int size;
    int queue_full_retries = 0;
    char *out_buf;
    size_t out_size;
    struct flb_kafka_topic *topic = NULL;
    msgpack_sbuffer mp_sbuf;
    msgpack_packer mp_pck;
    msgpack_object key;
    msgpack_object val;
    flb_sds_t s;

    /* Init temporal buffers */
    msgpack_sbuffer_init(&mp_sbuf);
    msgpack_packer_init(&mp_pck, &mp_sbuf, msgpack_sbuffer_write);

    if (ctx->format == FLB_KAFKA_FMT_JSON || ctx->format == FLB_KAFKA_FMT_MSGP) {
        /* Make room for the timestamp */
        size = map->via.map.size + 1;
        msgpack_pack_map(&mp_pck, size);

        /* Pack timestamp */
        msgpack_pack_str(&mp_pck, ctx->timestamp_key_len);
        msgpack_pack_str_body(&mp_pck,
                              ctx->timestamp_key, ctx->timestamp_key_len);
        switch (ctx->timestamp_format) {
            case FLB_JSON_DATE_DOUBLE:
                msgpack_pack_double(&mp_pck, flb_time_to_double(tm));
                break;

            case FLB_JSON_DATE_ISO8601:
                {
                size_t date_len;
                int len;
                struct tm _tm;
                char time_formatted[32];
                /* Format the time; use microsecond precision (not nanoseconds). */
                gmtime_r(&tm->tm.tv_sec, &_tm);
                date_len = strftime(time_formatted, sizeof(time_formatted) - 1,
                             FLB_JSON_DATE_ISO8601_FMT, &_tm);

                len = snprintf(time_formatted + date_len, sizeof(time_formatted) - 1 - date_len,
                               ".%06" PRIu64 "Z", (uint64_t) tm->tm.tv_nsec / 1000);
                date_len += len;

                msgpack_pack_str(&mp_pck, date_len);
                msgpack_pack_str_body(&mp_pck, time_formatted, date_len);
                }
                break;
        }
    }
    else {
        size = map->via.map.size;
        msgpack_pack_map(&mp_pck, size);
    }

    for (i = 0; i < map->via.map.size; i++) {
        key = map->via.map.ptr[i].key;
        val = map->via.map.ptr[i].val;

        msgpack_pack_object(&mp_pck, key);
        msgpack_pack_object(&mp_pck, val);

        /* Lookup key/topic */
        if (ctx->topic_key && !topic && val.type == MSGPACK_OBJECT_STR) {
            if (key.via.str.size == ctx->topic_key_len &&
                strncmp(key.via.str.ptr, ctx->topic_key, ctx->topic_key_len) == 0) {
                topic = flb_kafka_topic_lookup((char *) val.via.str.ptr,
                                               val.via.str.size,
                                               ctx);
            }
        }
    }

    if (ctx->format == FLB_KAFKA_FMT_JSON) {
        s = flb_msgpack_raw_to_json_sds(mp_sbuf.data, mp_sbuf.size);
        if (!s) {
            flb_error("[out_kafka] error encoding to JSON");
            msgpack_sbuffer_destroy(&mp_sbuf);
            return FLB_ERROR;
        }
        out_buf  = s;
        out_size = flb_sds_len(out_buf);
    }
    else if (ctx->format == FLB_KAFKA_FMT_MSGP) {
        out_buf = mp_sbuf.data;
        out_size = mp_sbuf.size;
    }
    else if (ctx->format == FLB_KAFKA_FMT_GELF) {
        s = flb_msgpack_raw_to_gelf(mp_sbuf.data, mp_sbuf.size,
{'fraction_non_alphanumeric': 0.11100832562442182, 'fraction_numerical': 0.00906567992599445, 'mean_word_length': 2.0105820105820107, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 59, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2100965', 'n_tokens_mistral': 3779, 'n_tokens_neox': 3622, 'n_words': 774}