logger.h revision aeaaf81c2cc8366ac4f66eb3d2fc85f9b8194982
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;
43  unsigned logMask; /* cache of available success */
44  union android_log_context context; /* Initialized by static allocation */
45
46  int (*available)(log_id_t logId);
47  int (*open)();
48  void (*close)();
49  int (*write)(log_id_t logId, struct timespec *ts, struct iovec *vec, size_t nr);
50};
51
52struct android_log_logger_list;
53struct android_log_transport_context;
54struct android_log_logger;
55
56struct android_log_transport_read {
57  struct listnode node;
58  const char *name;
59
60  int (*available)(log_id_t logId);
61  int (*version)(struct android_log_logger *logger,
62                 struct android_log_transport_context *transp);
63  void (*close)(struct android_log_logger_list *logger_list,
64                struct android_log_transport_context *transp);
65
66  /*
67   * Expect all to instantiate open on any call, so we do not have
68   * an expicit open call
69   */
70  int (*read)(struct android_log_logger_list *logger_list,
71              struct android_log_transport_context *transp,
72              struct log_msg *log_msg);
73  /* Assumption is only called if not ANDROID_LOG_NONBLOCK */
74  int (*poll)(struct android_log_logger_list *logger_list,
75              struct android_log_transport_context *transp);
76
77  int (*clear)(struct android_log_logger *logger,
78               struct android_log_transport_context *transp);
79  ssize_t (*setSize)(struct android_log_logger *logger,
80                     struct android_log_transport_context *transp,
81                     size_t size);
82  ssize_t (*getSize)(struct android_log_logger *logger,
83                     struct android_log_transport_context *transp);
84  ssize_t (*getReadableSize)(struct android_log_logger *logger,
85                             struct android_log_transport_context *transp);
86
87  ssize_t (*getPrune)(struct android_log_logger_list *logger_list,
88                      struct android_log_transport_context *transp,
89                      char *buf, size_t len);
90  ssize_t (*setPrune)(struct android_log_logger_list *logger_list,
91                      struct android_log_transport_context *transp,
92                      char *buf, size_t len);
93  ssize_t (*getStats)(struct android_log_logger_list *logger_list,
94                      struct android_log_transport_context *transp,
95                      char *buf, size_t len);
96};
97
98struct android_log_logger_list {
99  struct listnode logger;
100  struct listnode transport;
101  int mode;
102  unsigned int tail;
103  log_time start;
104  pid_t pid;
105};
106
107struct android_log_logger {
108  struct listnode node;
109  struct android_log_logger_list *parent;
110
111  log_id_t logId;
112};
113
114struct android_log_transport_context {
115  struct listnode node;
116  union android_log_context context; /* zero init per-transport context */
117  struct android_log_logger_list *parent;
118
119  struct android_log_transport_read *transport;
120  unsigned logMask;
121  int ret;
122  struct log_msg logMsg; /* valid is logMsg.len != 0 */
123};
124
125/* assumes caller has structures read-locked, single threaded, or fenced */
126#define transport_context_for_each(transp, logger_list)              \
127  for ((transp) = node_to_item((logger_list)->transport.next,        \
128                             struct android_log_transport_context,   \
129                             node);                                  \
130       ((transp) != node_to_item(&(logger_list)->transport,          \
131                               struct android_log_transport_context, \
132                               node)) &&                             \
133           ((transp)->parent == (logger_list));                      \
134       (transp) = node_to_item((transp)->node.next,                  \
135                             struct android_log_transport_context, node))
136
137#define logger_for_each(logp, logger_list)                          \
138    for ((logp) = node_to_item((logger_list)->logger.next,          \
139                             struct android_log_logger, node);      \
140         ((logp) != node_to_item(&(logger_list)->logger,            \
141                               struct android_log_logger, node)) && \
142             ((logp)->parent == (logger_list));                     \
143         (logp) = node_to_item((logp)->node.next,                   \
144                             struct android_log_logger, node))
145
146/* OS specific dribs and drabs */
147
148#if defined(_WIN32)
149#include <private/android_filesystem_config.h>
150typedef uint32_t uid_t;
151static inline uid_t __android_log_uid() { return AID_SYSTEM; }
152#else
153static inline uid_t __android_log_uid() { return getuid(); }
154#endif
155
156LIBLOG_HIDDEN void __android_log_lock();
157LIBLOG_HIDDEN int __android_log_trylock();
158LIBLOG_HIDDEN void __android_log_unlock();
159
160__END_DECLS
161
162#endif /* _LIBLOG_LOGGER_H__ */
163