Create stats_buffer_writer
Move iovec* construction and noteLogLoss from stats_event_list to stats_buffer_writer.h. Expose write_buffer_to_statsd that takes in a byte array and writes it to the statsd socket. Currently exposed for StatsLog.write JNI call. This change also allows getting rid of stats_event_list once all clients have migrated to stats_event Bug: 145619049 Test: m -j libstatssocket Change-Id: I0048e392c2f5039eb70dacf4e91a43d3f32e8749
This commit is contained in:
parent
876f64cb2f
commit
f9b24aef5f
|
@ -20,7 +20,10 @@
|
|||
cc_library {
|
||||
name: "libstatssocket",
|
||||
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",
|
||||
"statsd_writer.c",
|
||||
],
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Copyright (C) 2019 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 <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif // __CPLUSPLUS
|
||||
void stats_log_close();
|
||||
int write_buffer_to_statsd(void* buffer, size_t size, uint32_t atomId);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif // __CPLUSPLUS
|
|
@ -76,7 +76,7 @@
|
|||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#endif // __CPLUSPLUS
|
||||
|
||||
struct stats_event;
|
||||
|
||||
|
@ -132,6 +132,6 @@ uint32_t stats_event_get_errors(struct stats_event* event);
|
|||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif // __CPLUSPLUS
|
||||
|
||||
#endif // ANDROID_STATS_LOG_STATS_EVENT_H
|
||||
|
|
|
@ -24,11 +24,9 @@ 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 atom_tag);
|
||||
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);
|
||||
extern int (*write_to_statsd)(struct iovec* vec, size_t nr);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,130 @@
|
|||
/*
|
||||
* Copyright (C) 2019 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_buffer_writer.h"
|
||||
#ifdef __ANDROID__
|
||||
#include <cutils/properties.h>
|
||||
#endif
|
||||
#include <errno.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/uio.h>
|
||||
#include "statsd_writer.h"
|
||||
|
||||
static const uint32_t kStatsEventTag = 1937006964;
|
||||
|
||||
extern struct android_log_transport_write statsdLoggerWrite;
|
||||
|
||||
static int __write_to_statsd_init(struct iovec* vec, size_t nr);
|
||||
static int (*__write_to_statsd)(struct iovec* vec, size_t nr) = __write_to_statsd_init;
|
||||
|
||||
void note_log_drop(int error, int atomId) {
|
||||
statsdLoggerWrite.noteDrop(error, atomId);
|
||||
}
|
||||
|
||||
void stats_log_close() {
|
||||
statsd_writer_init_lock();
|
||||
__write_to_statsd = __write_to_statsd_init;
|
||||
if (statsdLoggerWrite.close) {
|
||||
(*statsdLoggerWrite.close)();
|
||||
}
|
||||
statsd_writer_init_unlock();
|
||||
}
|
||||
|
||||
int write_buffer_to_statsd(void* buffer, size_t size, uint32_t atomId) {
|
||||
int ret = 1;
|
||||
|
||||
#ifdef __ANDROID__
|
||||
bool statsdEnabled = property_get_bool("ro.statsd.enable", true);
|
||||
#else
|
||||
bool statsdEnabled = false;
|
||||
#endif
|
||||
|
||||
if (statsdEnabled) {
|
||||
struct iovec vecs[2];
|
||||
vecs[0].iov_base = (void*)&kStatsEventTag;
|
||||
vecs[0].iov_len = sizeof(kStatsEventTag);
|
||||
vecs[1].iov_base = buffer;
|
||||
vecs[1].iov_len = size;
|
||||
|
||||
ret = __write_to_statsd(vecs, 2);
|
||||
|
||||
if (ret < 0) {
|
||||
note_log_drop(ret, atomId);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int __write_to_stats_daemon(struct iovec* vec, size_t nr) {
|
||||
int save_errno;
|
||||
struct timespec ts;
|
||||
size_t len, i;
|
||||
|
||||
for (len = i = 0; i < nr; ++i) {
|
||||
len += vec[i].iov_len;
|
||||
}
|
||||
if (!len) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
save_errno = errno;
|
||||
#if defined(__ANDROID__)
|
||||
clock_gettime(CLOCK_REALTIME, &ts);
|
||||
#else
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
ts.tv_sec = tv.tv_sec;
|
||||
ts.tv_nsec = tv.tv_usec * 1000;
|
||||
#endif
|
||||
|
||||
int ret = (int)(*statsdLoggerWrite.write)(&ts, vec, nr);
|
||||
errno = save_errno;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int __write_to_statsd_initialize_locked() {
|
||||
if (!statsdLoggerWrite.open || ((*statsdLoggerWrite.open)() < 0)) {
|
||||
if (statsdLoggerWrite.close) {
|
||||
(*statsdLoggerWrite.close)();
|
||||
return -ENODEV;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int __write_to_statsd_init(struct iovec* vec, size_t nr) {
|
||||
int ret, save_errno = errno;
|
||||
|
||||
statsd_writer_init_lock();
|
||||
|
||||
if (__write_to_statsd == __write_to_statsd_init) {
|
||||
ret = __write_to_statsd_initialize_locked();
|
||||
if (ret < 0) {
|
||||
statsd_writer_init_unlock();
|
||||
errno = save_errno;
|
||||
return ret;
|
||||
}
|
||||
|
||||
__write_to_statsd = __write_to_stats_daemon;
|
||||
}
|
||||
|
||||
statsd_writer_init_unlock();
|
||||
|
||||
ret = __write_to_statsd(vec, nr);
|
||||
errno = save_errno;
|
||||
return ret;
|
||||
}
|
|
@ -18,7 +18,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include "include/stats_event_list.h"
|
||||
#include "stats_buffer_writer.h"
|
||||
|
||||
#define STATS_EVENT_TAG 1937006964
|
||||
#define LOGGER_ENTRY_MAX_PAYLOAD 4068
|
||||
|
@ -323,11 +323,5 @@ void stats_event_build(struct stats_event* event) {
|
|||
void stats_event_write(struct stats_event* event) {
|
||||
stats_event_build(event);
|
||||
|
||||
// Prepare iovecs for write to statsd.
|
||||
struct iovec vecs[2];
|
||||
vecs[0].iov_base = &event->tag;
|
||||
vecs[0].iov_len = sizeof(event->tag);
|
||||
vecs[1].iov_base = &event->buf;
|
||||
vecs[1].iov_len = event->size;
|
||||
write_to_statsd(vecs, 2);
|
||||
write_buffer_to_statsd(&event->buf, event->size, event->atomId);
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
#include <string.h>
|
||||
#include <sys/time.h>
|
||||
#include "statsd_writer.h"
|
||||
#include "stats_buffer_writer.h"
|
||||
|
||||
#define MAX_EVENT_PAYLOAD (LOGGER_ENTRY_MAX_PAYLOAD - sizeof(int32_t))
|
||||
|
||||
|
@ -38,11 +38,6 @@ typedef struct {
|
|||
uint8_t storage[LOGGER_ENTRY_MAX_PAYLOAD];
|
||||
} android_log_context_internal;
|
||||
|
||||
extern struct android_log_transport_write statsdLoggerWrite;
|
||||
|
||||
static int __write_to_statsd_init(struct iovec* vec, size_t nr);
|
||||
int (*write_to_statsd)(struct iovec* vec, size_t nr) = __write_to_statsd_init;
|
||||
|
||||
// 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) {
|
||||
|
@ -92,12 +87,7 @@ int stats_write_list(android_log_context ctx) {
|
|||
msg += sizeof(uint8_t) + sizeof(uint8_t);
|
||||
}
|
||||
|
||||
struct iovec vec[2];
|
||||
vec[0].iov_base = &context->tag;
|
||||
vec[0].iov_len = sizeof(context->tag);
|
||||
vec[1].iov_base = (void*)msg;
|
||||
vec[1].iov_len = len;
|
||||
return write_to_statsd(vec, 2);
|
||||
return write_buffer_to_statsd((void*)msg, len, 0);
|
||||
}
|
||||
|
||||
int write_to_logger(android_log_context ctx, log_id_t id) {
|
||||
|
@ -120,80 +110,6 @@ int write_to_logger(android_log_context ctx, log_id_t id) {
|
|||
return retValue;
|
||||
}
|
||||
|
||||
void note_log_drop(int error, int tag) {
|
||||
statsdLoggerWrite.noteDrop(error, tag);
|
||||
}
|
||||
|
||||
void stats_log_close() {
|
||||
statsd_writer_init_lock();
|
||||
write_to_statsd = __write_to_statsd_init;
|
||||
if (statsdLoggerWrite.close) {
|
||||
(*statsdLoggerWrite.close)();
|
||||
}
|
||||
statsd_writer_init_unlock();
|
||||
}
|
||||
|
||||
/* log_init_lock assumed */
|
||||
static int __write_to_statsd_initialize_locked() {
|
||||
if (!statsdLoggerWrite.open || ((*statsdLoggerWrite.open)() < 0)) {
|
||||
if (statsdLoggerWrite.close) {
|
||||
(*statsdLoggerWrite.close)();
|
||||
return -ENODEV;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int __write_to_stats_daemon(struct iovec* vec, size_t nr) {
|
||||
int save_errno;
|
||||
struct timespec ts;
|
||||
size_t len, i;
|
||||
|
||||
for (len = i = 0; i < nr; ++i) {
|
||||
len += vec[i].iov_len;
|
||||
}
|
||||
if (!len) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
save_errno = errno;
|
||||
#if defined(__ANDROID__)
|
||||
clock_gettime(CLOCK_REALTIME, &ts);
|
||||
#else
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
ts.tv_sec = tv.tv_sec;
|
||||
ts.tv_nsec = tv.tv_usec * 1000;
|
||||
#endif
|
||||
|
||||
int ret = (int)(*statsdLoggerWrite.write)(&ts, vec, nr);
|
||||
errno = save_errno;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int __write_to_statsd_init(struct iovec* vec, size_t nr) {
|
||||
int ret, save_errno = errno;
|
||||
|
||||
statsd_writer_init_lock();
|
||||
|
||||
if (write_to_statsd == __write_to_statsd_init) {
|
||||
ret = __write_to_statsd_initialize_locked();
|
||||
if (ret < 0) {
|
||||
statsd_writer_init_unlock();
|
||||
errno = save_errno;
|
||||
return ret;
|
||||
}
|
||||
|
||||
write_to_statsd = __write_to_stats_daemon;
|
||||
}
|
||||
|
||||
statsd_writer_init_unlock();
|
||||
|
||||
ret = write_to_statsd(vec, nr);
|
||||
errno = save_errno;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline void copy4LE(uint8_t* buf, uint32_t val) {
|
||||
buf[0] = val & 0xFF;
|
||||
buf[1] = (val >> 8) & 0xFF;
|
||||
|
|
Loading…
Reference in New Issue