Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d430c85c authored by Ruchir Rastogi's avatar Ruchir Rastogi Committed by Android (Google) Code Review
Browse files

Merge "Delete stats_event_list from libstatssocket"

parents ea37af2c e1cff242
Loading
Loading
Loading
Loading
+2 −11
Original line number Diff line number Diff line
@@ -22,9 +22,6 @@ cc_library {
    srcs: [
        "stats_buffer_writer.c",
        "stats_event.c",
        // TODO(b/145573568): Remove stats_event_list once stats_event
        // migration is complete.
        "stats_event_list.c",
        "stats_socket.c",
        "statsd_writer.c",
    ],
@@ -32,14 +29,10 @@ cc_library {
    cflags: [
        "-Wall",
        "-Werror",
        "-DLIBLOG_LOG_TAG=1006",
        "-DWRITE_TO_STATSD=1",
        "-DWRITE_TO_LOGD=0",
    ],
    export_include_dirs: ["include"],
    shared_libs: [
        "libcutils",
        "liblog",
    static_libs: [
        "libcutils", // does not expose a stable C API
    ],

    // enumerate stable entry points for APEX use
@@ -78,7 +71,6 @@ cc_benchmark {
    ],
    shared_libs: [
        "libcutils",
        "liblog",
        "libgtest_prod",
    ],
}
@@ -96,7 +88,6 @@ cc_test {
    ],
    shared_libs: [
        "libcutils",
        "liblog",
        "libutils",
    ],
    test_suites: ["device-tests"],
+0 −248
Original line number Diff line number Diff line
/*
 * Copyright (C) 2018, The Android Open Source Project
 *
 * 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.
 */

#pragma once

#include <log/log_event_list.h>
#include <sys/uio.h>

#ifdef __cplusplus
extern "C" {
#endif
void reset_log_context(android_log_context ctx);
int write_to_logger(android_log_context context, log_id_t id);
void note_log_drop(int error, int atomId);
void stats_log_close();
int android_log_write_char_array(android_log_context ctx, const char* value, size_t len);
#ifdef __cplusplus
}
#endif

#ifdef __cplusplus
/**
 * A copy of android_log_event_list class.
 *
 * android_log_event_list is going to be deprecated soon, so copy it here to
 * avoid creating dependency on upstream code. TODO(b/78304629): Rewrite this
 * code.
 */
class stats_event_list {
  private:
    android_log_context ctx;
    int ret;

    stats_event_list(const stats_event_list&) = delete;
    void operator=(const stats_event_list&) = delete;

  public:
    explicit stats_event_list(int tag) : ret(0) {
        ctx = create_android_logger(static_cast<uint32_t>(tag));
    }
    ~stats_event_list() { android_log_destroy(&ctx); }

    int close() {
        int retval = android_log_destroy(&ctx);
        if (retval < 0) {
            ret = retval;
        }
        return retval;
    }

    /* To allow above C calls to use this class as parameter */
    operator android_log_context() const { return ctx; }

    /* return errors or transmit status */
    int status() const { return ret; }

    int begin() {
        int retval = android_log_write_list_begin(ctx);
        if (retval < 0) {
            ret = retval;
        }
        return ret;
    }
    int end() {
        int retval = android_log_write_list_end(ctx);
        if (retval < 0) {
            ret = retval;
        }
        return ret;
    }

    stats_event_list& operator<<(int32_t value) {
        int retval = android_log_write_int32(ctx, value);
        if (retval < 0) {
            ret = retval;
        }
        return *this;
    }

    stats_event_list& operator<<(uint32_t value) {
        int retval = android_log_write_int32(ctx, static_cast<int32_t>(value));
        if (retval < 0) {
            ret = retval;
        }
        return *this;
    }

    stats_event_list& operator<<(bool value) {
        int retval = android_log_write_int32(ctx, value ? 1 : 0);
        if (retval < 0) {
            ret = retval;
        }
        return *this;
    }

    stats_event_list& operator<<(int64_t value) {
        int retval = android_log_write_int64(ctx, value);
        if (retval < 0) {
            ret = retval;
        }
        return *this;
    }

    stats_event_list& operator<<(uint64_t value) {
        int retval = android_log_write_int64(ctx, static_cast<int64_t>(value));
        if (retval < 0) {
            ret = retval;
        }
        return *this;
    }

    stats_event_list& operator<<(const char* value) {
        int retval = android_log_write_string8(ctx, value);
        if (retval < 0) {
            ret = retval;
        }
        return *this;
    }

    stats_event_list& operator<<(const std::string& value) {
        int retval = android_log_write_string8_len(ctx, value.data(), value.length());
        if (retval < 0) {
            ret = retval;
        }
        return *this;
    }

    stats_event_list& operator<<(float value) {
        int retval = android_log_write_float32(ctx, value);
        if (retval < 0) {
            ret = retval;
        }
        return *this;
    }

    int write(log_id_t id = LOG_ID_EVENTS) {
        /* facilitate -EBUSY retry */
        if ((ret == -EBUSY) || (ret > 0)) {
            ret = 0;
        }
        int retval = write_to_logger(ctx, id);
        /* existing errors trump transmission errors */
        if (!ret) {
            ret = retval;
        }
        return ret;
    }

    /*
     * Append<Type> methods removes any integer promotion
     * confusion, and adds access to string with length.
     * Append methods are also added for all types for
     * convenience.
     */

    bool AppendInt(int32_t value) {
        int retval = android_log_write_int32(ctx, value);
        if (retval < 0) {
            ret = retval;
        }
        return ret >= 0;
    }

    bool AppendLong(int64_t value) {
        int retval = android_log_write_int64(ctx, value);
        if (retval < 0) {
            ret = retval;
        }
        return ret >= 0;
    }

    bool AppendString(const char* value) {
        int retval = android_log_write_string8(ctx, value);
        if (retval < 0) {
            ret = retval;
        }
        return ret >= 0;
    }

    bool AppendString(const char* value, size_t len) {
        int retval = android_log_write_string8_len(ctx, value, len);
        if (retval < 0) {
            ret = retval;
        }
        return ret >= 0;
    }

    bool AppendString(const std::string& value) {
        int retval = android_log_write_string8_len(ctx, value.data(), value.length());
        if (retval < 0) {
            ret = retval;
        }
        return ret;
    }

    bool Append(const std::string& value) {
        int retval = android_log_write_string8_len(ctx, value.data(), value.length());
        if (retval < 0) {
            ret = retval;
        }
        return ret;
    }

    bool AppendFloat(float value) {
        int retval = android_log_write_float32(ctx, value);
        if (retval < 0) {
            ret = retval;
        }
        return ret >= 0;
    }

    template <typename Tvalue>
    bool Append(Tvalue value) {
        *this << value;
        return ret >= 0;
    }

    bool Append(const char* value, size_t len) {
        int retval = android_log_write_string8_len(ctx, value, len);
        if (retval < 0) {
            ret = retval;
        }
        return ret >= 0;
    }

    bool AppendCharArray(const char* value, size_t len) {
        int retval = android_log_write_char_array(ctx, value, len);
        if (retval < 0) {
            ret = retval;
        }
        return ret >= 0;
    }
};

#endif
+0 −155
Original line number Diff line number Diff line
/*
 * Copyright (C) 2018, The Android Open Source Project
 *
 * 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 "include/stats_event_list.h"

#include <string.h>
#include <sys/time.h>
#include "stats_buffer_writer.h"

#define MAX_EVENT_PAYLOAD (LOGGER_ENTRY_MAX_PAYLOAD - sizeof(int32_t))

typedef struct {
    uint32_t tag;
    unsigned pos;                                    /* Read/write position into buffer */
    unsigned count[ANDROID_MAX_LIST_NEST_DEPTH + 1]; /* Number of elements   */
    unsigned list[ANDROID_MAX_LIST_NEST_DEPTH + 1];  /* pos for list counter */
    unsigned list_nest_depth;
    unsigned len; /* Length or raw buffer. */
    bool overflow;
    bool list_stop; /* next call decrement list_nest_depth and issue a stop */
    enum {
        kAndroidLoggerRead = 1,
        kAndroidLoggerWrite = 2,
    } read_write_flag;
    uint8_t storage[LOGGER_ENTRY_MAX_PAYLOAD];
} android_log_context_internal;

// Similar to create_android_logger(), but instead of allocation a new buffer,
// this function resets the buffer for resuse.
void reset_log_context(android_log_context ctx) {
    if (!ctx) {
        return;
    }
    android_log_context_internal* context = (android_log_context_internal*)(ctx);
    uint32_t tag = context->tag;
    memset(context, 0, sizeof(android_log_context_internal));

    context->tag = tag;
    context->read_write_flag = kAndroidLoggerWrite;
    size_t needed = sizeof(uint8_t) + sizeof(uint8_t);
    if ((context->pos + needed) > MAX_EVENT_PAYLOAD) {
        context->overflow = true;
    }
    /* Everything is a list */
    context->storage[context->pos + 0] = EVENT_TYPE_LIST;
    context->list[0] = context->pos + 1;
    context->pos += needed;
}

int stats_write_list(android_log_context ctx) {
    android_log_context_internal* context;
    const char* msg;
    ssize_t len;

    context = (android_log_context_internal*)(ctx);
    if (!context || (kAndroidLoggerWrite != context->read_write_flag)) {
        return -EBADF;
    }

    if (context->list_nest_depth) {
        return -EIO;
    }

    /* NB: if there was overflow, then log is truncated. Nothing reported */
    context->storage[1] = context->count[0];
    len = context->len = context->pos;
    msg = (const char*)context->storage;
    /* it's not a list */
    if (context->count[0] <= 1) {
        len -= sizeof(uint8_t) + sizeof(uint8_t);
        if (len < 0) {
            len = 0;
        }
        msg += sizeof(uint8_t) + sizeof(uint8_t);
    }

    return write_buffer_to_statsd((void*)msg, len, 0);
}

int write_to_logger(android_log_context ctx, log_id_t id) {
    int retValue = 0;

    if (WRITE_TO_LOGD) {
        retValue = android_log_write_list(ctx, id);
    }

    if (WRITE_TO_STATSD) {
        // log_event_list's cast operator is overloaded.
        int ret = stats_write_list(ctx);
        // In debugging phase, we may write to both logd and statsd. Prefer to
        // return statsd socket write error code here.
        if (ret < 0) {
            retValue = ret;
        }
    }

    return retValue;
}

static inline void copy4LE(uint8_t* buf, uint32_t val) {
    buf[0] = val & 0xFF;
    buf[1] = (val >> 8) & 0xFF;
    buf[2] = (val >> 16) & 0xFF;
    buf[3] = (val >> 24) & 0xFF;
}

// Note: this function differs from android_log_write_string8_len in that the length passed in
// should be treated as actual length and not max length.
int android_log_write_char_array(android_log_context ctx, const char* value, size_t actual_len) {
    size_t needed;
    ssize_t len = actual_len;
    android_log_context_internal* context;

    context = (android_log_context_internal*)ctx;
    if (!context || (kAndroidLoggerWrite != context->read_write_flag)) {
        return -EBADF;
    }
    if (context->overflow) {
        return -EIO;
    }
    if (!value) {
        value = "";
        len = 0;
    }
    needed = sizeof(uint8_t) + sizeof(int32_t) + len;
    if ((context->pos + needed) > MAX_EVENT_PAYLOAD) {
        /* Truncate string for delivery */
        len = MAX_EVENT_PAYLOAD - context->pos - 1 - sizeof(int32_t);
        if (len <= 0) {
            context->overflow = true;
            return -EIO;
        }
    }
    context->count[context->list_nest_depth]++;
    context->storage[context->pos + 0] = EVENT_TYPE_STRING;
    copy4LE(&context->storage[context->pos + 1], len);
    if (len) {
        memcpy(&context->storage[context->pos + 5], value, len);
    }
    context->pos += needed;
    return len;
}