logger.h revision cf983bcbae801e4660521b9747d9a7516e7df1c1
1/* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#ifndef _LIBLOG_LOGGER_H__ 18#define _LIBLOG_LOGGER_H__ 19 20#include <stdatomic.h> 21#include <stdbool.h> 22 23#include <cutils/list.h> 24#include <log/log.h> 25#include <log/uio.h> 26 27#include "log_portability.h" 28 29__BEGIN_DECLS 30 31/* Union, sock or fd of zero is not allowed unless static initialized */ 32union android_log_context { 33 void *private; 34 atomic_int sock; 35 atomic_int fd; 36 struct listnode *node; 37 atomic_uintptr_t atomic_pointer; 38}; 39 40struct android_log_transport_write { 41 struct listnode node; 42 const char *name; /* human name to describe the transport */ 43 unsigned logMask; /* mask cache of available() success */ 44 union android_log_context context; /* Initialized by static allocation */ 45 46 int (*available)(log_id_t logId); /* Does not cause resources to be taken */ 47 int (*open)(); /* can be called multiple times, reusing current resources */ 48 void (*close)(); /* free up resources */ 49 /* write log to transport, returns number of bytes propagated, or -errno */ 50 int (*write)(log_id_t logId, struct timespec *ts, 51 struct iovec *vec, size_t nr); 52}; 53 54struct android_log_logger_list; 55struct android_log_transport_context; 56struct android_log_logger; 57 58struct android_log_transport_read { 59 struct listnode node; 60 const char *name; /* human name to describe the transport */ 61 62 /* Does not cause resources to be taken */ 63 int (*available)(log_id_t logId); 64 int (*version)(struct android_log_logger *logger, 65 struct android_log_transport_context *transp); 66 /* Release resources taken by the following interfaces */ 67 void (*close)(struct android_log_logger_list *logger_list, 68 struct android_log_transport_context *transp); 69 /* 70 * Expect all to instantiate open automagically on any call, 71 * so we do not have an explicit open call. 72 */ 73 int (*read)(struct android_log_logger_list *logger_list, 74 struct android_log_transport_context *transp, 75 struct log_msg *log_msg); 76 /* Must only be called if not ANDROID_LOG_NONBLOCK (blocking) */ 77 int (*poll)(struct android_log_logger_list *logger_list, 78 struct android_log_transport_context *transp); 79 80 int (*clear)(struct android_log_logger *logger, 81 struct android_log_transport_context *transp); 82 ssize_t (*setSize)(struct android_log_logger *logger, 83 struct android_log_transport_context *transp, 84 size_t size); 85 ssize_t (*getSize)(struct android_log_logger *logger, 86 struct android_log_transport_context *transp); 87 ssize_t (*getReadableSize)(struct android_log_logger *logger, 88 struct android_log_transport_context *transp); 89 90 ssize_t (*getPrune)(struct android_log_logger_list *logger_list, 91 struct android_log_transport_context *transp, 92 char *buf, size_t len); 93 ssize_t (*setPrune)(struct android_log_logger_list *logger_list, 94 struct android_log_transport_context *transp, 95 char *buf, size_t len); 96 ssize_t (*getStats)(struct android_log_logger_list *logger_list, 97 struct android_log_transport_context *transp, 98 char *buf, size_t len); 99}; 100 101struct android_log_logger_list { 102 struct listnode node; 103 struct listnode logger; 104 struct listnode transport; 105 int mode; 106 unsigned int tail; 107 log_time start; 108 pid_t pid; 109}; 110 111struct android_log_logger { 112 struct listnode node; 113 struct android_log_logger_list *parent; 114 115 log_id_t logId; 116}; 117 118struct android_log_transport_context { 119 struct listnode node; 120 union android_log_context context; /* zero init per-transport context */ 121 struct android_log_logger_list *parent; 122 123 struct android_log_transport_read *transport; 124 unsigned logMask; /* mask of requested log buffers */ 125 int ret; /* return value associated with following data */ 126 struct log_msg logMsg; /* peek at upcoming data, valid if logMsg.len != 0 */ 127}; 128 129/* assumes caller has structures read-locked, single threaded, or fenced */ 130#define transport_context_for_each(transp, logger_list) \ 131 for ((transp) = node_to_item((logger_list)->transport.next, \ 132 struct android_log_transport_context, \ 133 node); \ 134 ((transp) != node_to_item(&(logger_list)->transport, \ 135 struct android_log_transport_context, \ 136 node)) && \ 137 ((transp)->parent == (logger_list)); \ 138 (transp) = node_to_item((transp)->node.next, \ 139 struct android_log_transport_context, node)) 140 141#define logger_for_each(logp, logger_list) \ 142 for ((logp) = node_to_item((logger_list)->logger.next, \ 143 struct android_log_logger, node); \ 144 ((logp) != node_to_item(&(logger_list)->logger, \ 145 struct android_log_logger, node)) && \ 146 ((logp)->parent == (logger_list)); \ 147 (logp) = node_to_item((logp)->node.next, \ 148 struct android_log_logger, node)) 149 150/* 151 * Global list of log readers. 152 * 153 * Usage case: search out transport contexts for all readers 154 */ 155 156LIBLOG_HIDDEN struct listnode __android_log_readers; 157 158#if defined(_WIN32) 159#define logger_list_rdlock() 160#define logger_list_wrlock() 161#define logger_list_unlock() 162#else 163LIBLOG_HIDDEN pthread_rwlock_t __android_log_readers_lock; 164 165#define logger_list_rdlock() pthread_rwlock_rdlock(&__android_log_readers_lock) 166#define logger_list_wrlock() pthread_rwlock_wrlock(&__android_log_readers_lock) 167#define logger_list_unlock() pthread_rwlock_unlock(&__android_log_readers_lock) 168#endif 169 170/* Must be called with logger_list_rdlock() or logger_list_wrlock() held */ 171#define logger_list_for_each(logger_list) \ 172 for ((logger_list) = node_to_item(&__android_log_readers, \ 173 struct android_log_logger_list, \ 174 node); \ 175 (logger_list) != node_to_item(&__android_log_readers, \ 176 struct android_log_logger_list, \ 177 node) && \ 178 (logger_list) != node_to_item((logger_list)->node.next, \ 179 struct android_log_logger_list, \ 180 node); \ 181 (logger_list) = node_to_item((logger_list)->node.next, \ 182 struct android_log_logger_list, \ 183 node)) 184 185/* OS specific dribs and drabs */ 186 187#if defined(_WIN32) 188#include <private/android_filesystem_config.h> 189typedef uint32_t uid_t; 190static inline uid_t __android_log_uid() { return AID_SYSTEM; } 191#else 192static inline uid_t __android_log_uid() { return getuid(); } 193#endif 194 195LIBLOG_HIDDEN void __android_log_lock(); 196LIBLOG_HIDDEN int __android_log_trylock(); 197LIBLOG_HIDDEN void __android_log_unlock(); 198 199__END_DECLS 200 201#endif /* _LIBLOG_LOGGER_H__ */ 202