summaryrefslogtreecommitdiffstats
path: root/include/log
diff options
context:
space:
mode:
Diffstat (limited to 'include/log')
-rw-r--r--include/log/log.h24
-rw-r--r--include/log/log_read.h101
-rw-r--r--include/log/logd.h1
-rw-r--r--include/log/logger.h55
4 files changed, 144 insertions, 37 deletions
diff --git a/include/log/log.h b/include/log/log.h
index 7f952ff..ace12d6 100644
--- a/include/log/log.h
+++ b/include/log/log.h
@@ -73,10 +73,11 @@ extern "C" {
* Simplified macro to send a verbose log message using the current LOG_TAG.
*/
#ifndef ALOGV
+#define __ALOGV(...) ((void)ALOG(LOG_VERBOSE, LOG_TAG, __VA_ARGS__))
#if LOG_NDEBUG
-#define ALOGV(...) ((void)0)
+#define ALOGV(...) do { if (0) { __ALOGV(__VA_ARGS__); } } while (0)
#else
-#define ALOGV(...) ((void)ALOG(LOG_VERBOSE, LOG_TAG, __VA_ARGS__))
+#define ALOGV(...) __ALOGV(__VA_ARGS__)
#endif
#endif
@@ -202,10 +203,11 @@ extern "C" {
* Simplified macro to send a verbose system log message using the current LOG_TAG.
*/
#ifndef SLOGV
+#define __SLOGV(...) ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__))
#if LOG_NDEBUG
-#define SLOGV(...) ((void)0)
+#define SLOGV(...) do { if (0) { __SLOGV(__VA_ARGS__); } } while (0)
#else
-#define SLOGV(...) ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__))
+#define SLOGV(...) __SLOGV(__VA_ARGS__)
#endif
#endif
@@ -284,10 +286,11 @@ extern "C" {
* Simplified macro to send a verbose radio log message using the current LOG_TAG.
*/
#ifndef RLOGV
+#define __RLOGV(...) ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__))
#if LOG_NDEBUG
-#define RLOGV(...) ((void)0)
+#define RLOGV(...) do { if (0) { __RLOGV(__VA_ARGS__); } } while (0)
#else
-#define RLOGV(...) ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__))
+#define RLOGV(...) __RLOGV(__VA_ARGS__)
#endif
#endif
@@ -488,7 +491,7 @@ typedef enum {
#endif
#ifndef LOG_EVENT_STRING
#define LOG_EVENT_STRING(_tag, _value) \
- ((void) 0) /* not implemented -- must combine len with string */
+ (void) __android_log_bswrite(_tag, _value);
#endif
/* TODO: something for LIST */
@@ -547,6 +550,7 @@ typedef enum log_id {
LOG_ID_RADIO = 1,
LOG_ID_EVENTS = 2,
LOG_ID_SYSTEM = 3,
+ LOG_ID_CRASH = 4,
LOG_ID_MAX
} log_id_t;
@@ -557,7 +561,11 @@ typedef enum log_id {
* Send a simple string to the log.
*/
int __android_log_buf_write(int bufID, int prio, const char *tag, const char *text);
-int __android_log_buf_print(int bufID, int prio, const char *tag, const char *fmt, ...);
+int __android_log_buf_print(int bufID, int prio, const char *tag, const char *fmt, ...)
+#if defined(__GNUC__)
+ __attribute__((__format__(printf, 4, 5)))
+#endif
+ ;
#ifdef __cplusplus
}
diff --git a/include/log/log_read.h b/include/log/log_read.h
index 861c192..946711a 100644
--- a/include/log/log_read.h
+++ b/include/log/log_read.h
@@ -17,23 +17,45 @@
#ifndef _LIBS_LOG_LOG_READ_H
#define _LIBS_LOG_LOG_READ_H
+#include <stdint.h>
#include <time.h>
+/* struct log_time is a wire-format variant of struct timespec */
#define NS_PER_SEC 1000000000ULL
+
#ifdef __cplusplus
-struct log_time : public timespec {
+
+// NB: do NOT define a copy constructor. This will result in structure
+// no longer being compatible with pass-by-value which is desired
+// efficient behavior. Also, pass-by-reference breaks C/C++ ABI.
+struct log_time {
public:
- log_time(timespec &T)
+ uint32_t tv_sec; // good to Feb 5 2106
+ uint32_t tv_nsec;
+
+ static const uint32_t tv_sec_max = 0xFFFFFFFFUL;
+ static const uint32_t tv_nsec_max = 999999999UL;
+
+ log_time(const timespec &T)
{
tv_sec = T.tv_sec;
tv_nsec = T.tv_nsec;
}
- log_time(void)
+ log_time(uint32_t sec, uint32_t nsec)
+ {
+ tv_sec = sec;
+ tv_nsec = nsec;
+ }
+ static const timespec EPOCH;
+ log_time()
{
}
log_time(clockid_t id)
{
- clock_gettime(id, (timespec *) this);
+ timespec T;
+ clock_gettime(id, &T);
+ tv_sec = T.tv_sec;
+ tv_nsec = T.tv_nsec;
}
log_time(const char *T)
{
@@ -41,9 +63,12 @@ public:
tv_sec = c[0] | (c[1] << 8) | (c[2] << 16) | (c[3] << 24);
tv_nsec = c[4] | (c[5] << 8) | (c[6] << 16) | (c[7] << 24);
}
+
+ // timespec
bool operator== (const timespec &T) const
{
- return (tv_sec == T.tv_sec) && (tv_nsec == T.tv_nsec);
+ return (tv_sec == static_cast<uint32_t>(T.tv_sec))
+ && (tv_nsec == static_cast<uint32_t>(T.tv_nsec));
}
bool operator!= (const timespec &T) const
{
@@ -51,8 +76,9 @@ public:
}
bool operator< (const timespec &T) const
{
- return (tv_sec < T.tv_sec)
- || ((tv_sec == T.tv_sec) && (tv_nsec < T.tv_nsec));
+ return (tv_sec < static_cast<uint32_t>(T.tv_sec))
+ || ((tv_sec == static_cast<uint32_t>(T.tv_sec))
+ && (tv_nsec < static_cast<uint32_t>(T.tv_nsec)));
}
bool operator>= (const timespec &T) const
{
@@ -60,20 +86,73 @@ public:
}
bool operator> (const timespec &T) const
{
+ return (tv_sec > static_cast<uint32_t>(T.tv_sec))
+ || ((tv_sec == static_cast<uint32_t>(T.tv_sec))
+ && (tv_nsec > static_cast<uint32_t>(T.tv_nsec)));
+ }
+ bool operator<= (const timespec &T) const
+ {
+ return !(*this > T);
+ }
+ log_time operator-= (const timespec &T);
+ log_time operator- (const timespec &T) const
+ {
+ log_time local(*this);
+ return local -= T;
+ }
+
+ // log_time
+ bool operator== (const log_time &T) const
+ {
+ return (tv_sec == T.tv_sec) && (tv_nsec == T.tv_nsec);
+ }
+ bool operator!= (const log_time &T) const
+ {
+ return !(*this == T);
+ }
+ bool operator< (const log_time &T) const
+ {
+ return (tv_sec < T.tv_sec)
+ || ((tv_sec == T.tv_sec) && (tv_nsec < T.tv_nsec));
+ }
+ bool operator>= (const log_time &T) const
+ {
+ return !(*this < T);
+ }
+ bool operator> (const log_time &T) const
+ {
return (tv_sec > T.tv_sec)
|| ((tv_sec == T.tv_sec) && (tv_nsec > T.tv_nsec));
}
- bool operator<= (const timespec &T) const
+ bool operator<= (const log_time &T) const
{
return !(*this > T);
}
- uint64_t nsec(void) const
+ log_time operator-= (const log_time &T);
+ log_time operator- (const log_time &T) const
+ {
+ log_time local(*this);
+ return local -= T;
+ }
+
+ uint64_t nsec() const
{
return static_cast<uint64_t>(tv_sec) * NS_PER_SEC + tv_nsec;
}
-};
+
+ static const char default_format[];
+
+ // Add %#q for the fraction of a second to the standard library functions
+ char *strptime(const char *s, const char *format = default_format);
+} __attribute__((__packed__));
+
#else
-typedef struct timespec log_time;
+
+typedef struct log_time {
+ uint32_t tv_sec;
+ uint32_t tv_nsec;
+} __attribute__((__packed__)) log_time;
+
#endif
#endif /* define _LIBS_LOG_LOG_READ_H */
diff --git a/include/log/logd.h b/include/log/logd.h
index 379c373..2e6f220 100644
--- a/include/log/logd.h
+++ b/include/log/logd.h
@@ -41,6 +41,7 @@ extern "C" {
int __android_log_bwrite(int32_t tag, const void *payload, size_t len);
int __android_log_btwrite(int32_t tag, char type, const void *payload,
size_t len);
+int __android_log_bswrite(int32_t tag, const char *payload);
#ifdef __cplusplus
}
diff --git a/include/log/logger.h b/include/log/logger.h
index 966397a..53be1d3 100644
--- a/include/log/logger.h
+++ b/include/log/logger.h
@@ -12,6 +12,7 @@
#include <stdint.h>
#include <log/log.h>
+#include <log/log_read.h>
#ifdef __cplusplus
extern "C" {
@@ -30,12 +31,12 @@ struct logger_entry {
int32_t sec; /* seconds since Epoch */
int32_t nsec; /* nanoseconds */
char msg[0]; /* the entry's payload */
-};
+} __attribute__((__packed__));
/*
* The userspace structure for version 2 of the logger_entry ABI.
* This structure is returned to userspace if ioctl(LOGGER_SET_VERSION)
- * is called with version==2
+ * is called with version==2; or used with the user space log daemon.
*/
struct logger_entry_v2 {
uint16_t len; /* length of the payload */
@@ -46,13 +47,23 @@ struct logger_entry_v2 {
int32_t nsec; /* nanoseconds */
uint32_t euid; /* effective UID of logger */
char msg[0]; /* the entry's payload */
-};
+} __attribute__((__packed__));
+
+struct logger_entry_v3 {
+ uint16_t len; /* length of the payload */
+ uint16_t hdr_size; /* sizeof(struct logger_entry_v3) */
+ int32_t pid; /* generating process's pid */
+ int32_t tid; /* generating process's tid */
+ int32_t sec; /* seconds since Epoch */
+ int32_t nsec; /* nanoseconds */
+ uint32_t lid; /* log id of the payload */
+ char msg[0]; /* the entry's payload */
+} __attribute__((__packed__));
/*
* The maximum size of the log entry payload that can be
- * written to the kernel logger driver. An attempt to write
- * more than this amount to /dev/log/* will result in a
- * truncated log entry.
+ * written to the logger. An attempt to write more than
+ * this amount will result in a truncated log entry.
*/
#define LOGGER_ENTRY_MAX_PAYLOAD 4076
@@ -68,13 +79,10 @@ struct logger_entry_v2 {
struct log_msg {
union {
unsigned char buf[LOGGER_ENTRY_MAX_LEN + 1];
- struct logger_entry_v2 entry;
+ struct logger_entry_v3 entry;
+ struct logger_entry_v3 entry_v3;
struct logger_entry_v2 entry_v2;
struct logger_entry entry_v1;
- struct {
- unsigned char buf[LOGGER_ENTRY_MAX_LEN + 1];
- log_id_t id;
- } extra;
} __attribute__((aligned(4)));
#ifdef __cplusplus
/* Matching log_time operators */
@@ -106,21 +114,21 @@ struct log_msg {
{
return !(*this > T);
}
- uint64_t nsec(void) const
+ uint64_t nsec() const
{
return static_cast<uint64_t>(entry.sec) * NS_PER_SEC + entry.nsec;
}
/* packet methods */
- log_id_t id(void)
+ log_id_t id()
{
- return extra.id;
+ return (log_id_t) entry.lid;
}
- char *msg(void)
+ char *msg()
{
return entry.hdr_size ? (char *) buf + entry.hdr_size : entry_v1.msg;
}
- unsigned int len(void)
+ unsigned int len()
{
return (entry.hdr_size ? entry.hdr_size : sizeof(entry_v1)) + entry.len;
}
@@ -132,15 +140,26 @@ struct logger;
log_id_t android_logger_get_id(struct logger *logger);
int android_logger_clear(struct logger *logger);
-int android_logger_get_log_size(struct logger *logger);
-int android_logger_get_log_readable_size(struct logger *logger);
+long android_logger_get_log_size(struct logger *logger);
+int android_logger_set_log_size(struct logger *logger, unsigned long size);
+long android_logger_get_log_readable_size(struct logger *logger);
int android_logger_get_log_version(struct logger *logger);
struct logger_list;
+ssize_t android_logger_get_statistics(struct logger_list *logger_list,
+ char *buf, size_t len);
+ssize_t android_logger_get_prune_list(struct logger_list *logger_list,
+ char *buf, size_t len);
+int android_logger_set_prune_list(struct logger_list *logger_list,
+ char *buf, size_t len);
+
struct logger_list *android_logger_list_alloc(int mode,
unsigned int tail,
pid_t pid);
+struct logger_list *android_logger_list_alloc_time(int mode,
+ log_time start,
+ pid_t pid);
void android_logger_list_free(struct logger_list *logger_list);
/* In the purest sense, the following two are orthogonal interfaces */
int android_logger_list_read(struct logger_list *logger_list,