logger.h revision 81321a7980903fbdb42f6bd838445c651fd7996e
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* priv;
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, struct iovec* vec,
51               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, size_t size);
84  ssize_t (*getSize)(struct android_log_logger* logger,
85                     struct android_log_transport_context* transp);
86  ssize_t (*getReadableSize)(struct android_log_logger* logger,
87                             struct android_log_transport_context* transp);
88
89  ssize_t (*getPrune)(struct android_log_logger_list* logger_list,
90                      struct android_log_transport_context* transp, char* buf,
91                      size_t len);
92  ssize_t (*setPrune)(struct android_log_logger_list* logger_list,
93                      struct android_log_transport_context* transp, char* buf,
94                      size_t len);
95  ssize_t (*getStats)(struct android_log_logger_list* logger_list,
96                      struct android_log_transport_context* transp, char* buf,
97                      size_t len);
98};
99
100struct android_log_logger_list {
101  struct listnode node;
102  struct listnode logger;
103  struct listnode transport;
104  int mode;
105  unsigned int tail;
106  log_time start;
107  pid_t pid;
108};
109
110struct android_log_logger {
111  struct listnode node;
112  struct android_log_logger_list* parent;
113
114  log_id_t logId;
115};
116
117struct android_log_transport_context {
118  struct listnode node;
119  union android_log_context context; /* zero init per-transport context */
120  struct android_log_logger_list* parent;
121
122  struct android_log_transport_read* transport;
123  unsigned logMask;      /* mask of requested log buffers */
124  int ret;               /* return value associated with following data */
125  struct log_msg logMsg; /* peek at upcoming data, valid if logMsg.len != 0 */
126};
127
128/* assumes caller has structures read-locked, single threaded, or fenced */
129#define transport_context_for_each(transp, logger_list)                          \
130  for ((transp) = node_to_item((logger_list)->transport.next,                    \
131                               struct android_log_transport_context, node);      \
132       ((transp) != node_to_item(&(logger_list)->transport,                      \
133                                 struct android_log_transport_context, node)) && \
134       ((transp)->parent == (logger_list));                                      \
135       (transp) = node_to_item((transp)->node.next,                              \
136                               struct android_log_transport_context, node))
137
138#define logger_for_each(logp, logger_list)                          \
139  for ((logp) = node_to_item((logger_list)->logger.next,            \
140                             struct android_log_logger, node);      \
141       ((logp) != node_to_item(&(logger_list)->logger,              \
142                               struct android_log_logger, node)) && \
143       ((logp)->parent == (logger_list));                           \
144       (logp) =                                                     \
145           node_to_item((logp)->node.next, struct android_log_logger, node))
146
147/*
148 *    Global list of log readers.
149 *
150 * Usage case: search out transport contexts for all readers
151 */
152
153LIBLOG_HIDDEN struct listnode __android_log_readers;
154
155#if defined(_WIN32)
156#define logger_list_rdlock()
157#define logger_list_wrlock()
158#define logger_list_unlock()
159#else
160LIBLOG_HIDDEN pthread_rwlock_t __android_log_readers_lock;
161
162#define logger_list_rdlock() pthread_rwlock_rdlock(&__android_log_readers_lock)
163#define logger_list_wrlock() pthread_rwlock_wrlock(&__android_log_readers_lock)
164#define logger_list_unlock() pthread_rwlock_unlock(&__android_log_readers_lock)
165#endif
166
167/* Must be called with logger_list_rdlock() or logger_list_wrlock() held */
168#define logger_list_for_each(logger_list)                                     \
169  for ((logger_list) = node_to_item(&__android_log_readers,                   \
170                                    struct android_log_logger_list, node);    \
171       (logger_list) != node_to_item(&__android_log_readers,                  \
172                                     struct android_log_logger_list, node) && \
173       (logger_list) != node_to_item((logger_list)->node.next,                \
174                                     struct android_log_logger_list, node);   \
175       (logger_list) = node_to_item((logger_list)->node.next,                 \
176                                    struct android_log_logger_list, node))
177
178/* OS specific dribs and drabs */
179
180#if defined(_WIN32)
181#include <private/android_filesystem_config.h>
182typedef uint32_t uid_t;
183static inline uid_t __android_log_uid() {
184  return AID_SYSTEM;
185}
186#else
187static inline uid_t __android_log_uid() {
188  return getuid();
189}
190#endif
191
192LIBLOG_HIDDEN void __android_log_lock();
193LIBLOG_HIDDEN int __android_log_trylock();
194LIBLOG_HIDDEN void __android_log_unlock();
195
196LIBLOG_HIDDEN int __android_log_transport;
197
198__END_DECLS
199
200#endif /* _LIBLOG_LOGGER_H__ */
201