【Android】log系统初识

本来准备采用写/dev/log/main的方式进行底层的写log测试,但是Android6后就没有/dev/log/main了,根据参考资料来查看分析,

得到一个大致的概念,Android中由于log量大,为了方便的处理log,采用进程logd来写log,我们调用Log.d()方法写log的时候,会导致底层通过socket向logd进程写数据,logd将数据写到其缓存中,当使用logcat去获取数据的时候,也是通过socket通信去获取数据。

 

Log.d以及Slog的写log最终会调用到底层的方法

/system/core/liblog/logd_writer.c

117staticintlogdWrite(log_id_tlogId, structtimespec *ts,
118structiovec *vec, size_tnr)
119{
120ssize_tret;
121staticconstunsignedheaderLength = 1;
122structiovecnewVec[nr + headerLength];
123android_log_header_theader;
124size_t i, payloadSize;
125staticatomic_int_fast32_tdropped;
126staticatomic_int_fast32_tdroppedSecurity;
127128if (logdLoggerWrite.context.sock < 0) {
129return -EBADF;
130    }
131132/* logd, after initialization and priv drop */133if (__android_log_uid() == AID_LOGD) {
134/*
135         * ignore log messages we send to ourself (logd).
136         * Such log messages are often generated by libraries we depend on
137         * which use standard Android logging.
138         */139return 0;
140    }
141142/*
143     *  struct {
144     *      // what we provide to socket
145     *      android_log_header_t header;
146     *      // caller provides
147     *      union {
148     *          struct {
149     *              char     prio;
150     *              char     payload[];
151     *          } string;
152     *          struct {
153     *              uint32_t tag
154     *              char     payload[];
155     *          } binary;
156     *      };
157     *  };
158     */159160header.tid = gettid();
161header.realtime.tv_sec = ts->tv_sec;
162header.realtime.tv_nsec = ts->tv_nsec;
163164newVec[0].iov_base = (unsignedchar *)&header;
165newVec[0].iov_len  = sizeof(header);
166167if (logdLoggerWrite.context.sock > 0) {
168int32_tsnapshot = atomic_exchange_explicit(&droppedSecurity, 0,
169memory_order_relaxed);
170if (snapshot) {
171android_log_event_int_tbuffer;
172173header.id = LOG_ID_SECURITY;
174buffer.header.tag = htole32(LIBLOG_LOG_TAG);
175buffer.payload.type = EVENT_TYPE_INT;
176buffer.payload.data = htole32(snapshot);
177178newVec[headerLength].iov_base = &buffer;
179newVec[headerLength].iov_len  = sizeof(buffer);
180181ret = TEMP_FAILURE_RETRY(writev(logdLoggerWrite.context.sock, newVec, 2));
182if (ret != (ssize_t)(sizeof(header) + sizeof(buffer))) {
183atomic_fetch_add_explicit(&droppedSecurity, snapshot,
184memory_order_relaxed);
185            }
186        }

查看writev的定义

/system/core/liblog/uio.c

52LIBLOG_ABI_PUBLICintwritev(intfd, conststructiovec *vecs, intcount)
53{
54inttotal = 0;
5556for ( ; count > 0; count--, vecs++ ) {
57constchar*  buf = vecs->iov_base;
58intlen = vecs->iov_len;
5960while (len > 0) {
61intret = write( fd, buf, len );
62if (ret < 0) {
63if (total == 0)
64total = -1;
65gotoExit;
66            }
67if (ret == 0)
68gotoExit;
6970total += ret;
71buf   += ret;
72len   -= ret;
73        }
74    }
75Exit:
76returntotal;
77}
78

本质上还是调用的系统write方法,向logd进行写操作

也就是说,如果给入合适的输入格式,我们是可以直接通过write操作进行写log

如:

int main(int argc, char* const argv[])

{

        int fd = open("/dev/socket/logdw", O_RDWR);

        if (fd < 0)

                aerr << "fd < 0" << endl;

        else

                aout << "fd = " << fd << endl;

 

        write(fd, "=====00 log write===============", 22);

 

 

}

 

直接这样写是有问题的,数据格式不对,

Unknown:/data/local/tmp # ./wtLog

fd < 0

这个测试需要继续研究

 

如果要正确的处理,需要再查看logd的处理方式进行分析

logd启动后的入口是/system/core/logd/main.cpp中的main方法

 

logd对log进行处理,读log是从/dev/socket/logdr来获取数据

log处理流程

Log.d() -> liblog ---socket--->logd ----socket---->logcat

 

 

参考资料

 

本来准备采用写/dev/log/main的方式进行底层的写log测试,但是Android6后就没有/dev/log/main了,根据参考资料来查看

 

Log.d以及Slog的写log最终会调用到底层的方法

/system/core/liblog/logd_writer.c

117staticintlogdWrite(log_id_tlogId, structtimespec *ts,
118structiovec *vec, size_tnr)
119{
120ssize_tret;
121staticconstunsignedheaderLength = 1;
122structiovecnewVec[nr + headerLength];
123android_log_header_theader;
124size_t i, payloadSize;
125staticatomic_int_fast32_tdropped;
126staticatomic_int_fast32_tdroppedSecurity;
127128if (logdLoggerWrite.context.sock < 0) {
129return -EBADF;
130    }
131132/* logd, after initialization and priv drop */133if (__android_log_uid() == AID_LOGD) {
134/*
135         * ignore log messages we send to ourself (logd).
136         * Such log messages are often generated by libraries we depend on
137         * which use standard Android logging.
138         */139return 0;
140    }
141142/*
143     *  struct {
144     *      // what we provide to socket
145     *      android_log_header_t header;
146     *      // caller provides
147     *      union {
148     *          struct {
149     *              char     prio;
150     *              char     payload[];
151     *          } string;
152     *          struct {
153     *              uint32_t tag
154     *              char     payload[];
155     *          } binary;
156     *      };
157     *  };
158     */159160header.tid = gettid();
161header.realtime.tv_sec = ts->tv_sec;
162header.realtime.tv_nsec = ts->tv_nsec;
163164newVec[0].iov_base = (unsignedchar *)&header;
165newVec[0].iov_len  = sizeof(header);
166167if (logdLoggerWrite.context.sock > 0) {
168int32_tsnapshot = atomic_exchange_explicit(&droppedSecurity, 0,
169memory_order_relaxed);
170if (snapshot) {
171android_log_event_int_tbuffer;
172173header.id = LOG_ID_SECURITY;
174buffer.header.tag = htole32(LIBLOG_LOG_TAG);
175buffer.payload.type = EVENT_TYPE_INT;
176buffer.payload.data = htole32(snapshot);
177178newVec[headerLength].iov_base = &buffer;
179newVec[headerLength].iov_len  = sizeof(buffer);
180181ret = TEMP_FAILURE_RETRY(writev(logdLoggerWrite.context.sock, newVec, 2));
182if (ret != (ssize_t)(sizeof(header) + sizeof(buffer))) {
183atomic_fetch_add_explicit(&droppedSecurity, snapshot,
184memory_order_relaxed);
185            }
186        }

查看writev的定义

/system/core/liblog/uio.c

52LIBLOG_ABI_PUBLICintwritev(intfd, conststructiovec *vecs, intcount)
53{
54inttotal = 0;
5556for ( ; count > 0; count--, vecs++ ) {
57constchar*  buf = vecs->iov_base;
58intlen = vecs->iov_len;
5960while (len > 0) {
61intret = write( fd, buf, len );
62if (ret < 0) {
63if (total == 0)
64total = -1;
65gotoExit;
66            }
67if (ret == 0)
68gotoExit;
6970total += ret;
71buf   += ret;
72len   -= ret;
73        }
74    }
75Exit:
76returntotal;
77}
78

本质上还是调用的系统write方法,向logd进行写操作

也就是说,如果给入合适的输入格式,我们是可以直接通过write操作进行写log

如:

int main(int argc, char* const argv[])

{

        int fd = open("/dev/socket/logdw", O_RDWR);

        if (fd < 0)

                aerr << "fd < 0" << endl;

        else

                aout << "fd = " << fd << endl;

 

        write(fd, "=====00 log write===============", 22);

 

 

}

 

直接这样写是有问题的,数据格式不对,

Unknown:/data/local/tmp # ./wtLog

fd < 0

这个测试需要继续研究

 

如果要正确的处理,需要再查看logd的处理方式进行分析

logd启动后的入口是/system/core/logd/main.cpp中的main方法

 

logd对log进行处理,读log是从/dev/socket/logdr来获取数据

log处理流程

Log.d() -> liblog ---socket--->logd ----socket---->logcat

 

http://blog.csdn.net/KM_Cat/article/details/61320398

基于Android N的Log机制浅析

 

Android6的Logger日志系统

 

 

 

本来准备采用写/dev/log/main的方式进行底层的写log测试,但是Android6后就没有/dev/log/main了,根据参考资料来查看

 

Log.d以及Slog的写log最终会调用到底层的方法

/system/core/liblog/logd_writer.c

117staticintlogdWrite(log_id_tlogId, structtimespec *ts,
118structiovec *vec, size_tnr)
119{
120ssize_tret;
121staticconstunsignedheaderLength = 1;
122structiovecnewVec[nr + headerLength];
123android_log_header_theader;
124size_t i, payloadSize;
125staticatomic_int_fast32_tdropped;
126staticatomic_int_fast32_tdroppedSecurity;
127128if (logdLoggerWrite.context.sock < 0) {
129return -EBADF;
130    }
131132/* logd, after initialization and priv drop */133if (__android_log_uid() == AID_LOGD) {
134/*
135         * ignore log messages we send to ourself (logd).
136         * Such log messages are often generated by libraries we depend on
137         * which use standard Android logging.
138         */139return 0;
140    }
141142/*
143     *  struct {
144     *      // what we provide to socket
145     *      android_log_header_t header;
146     *      // caller provides
147     *      union {
148     *          struct {
149     *              char     prio;
150     *              char     payload[];
151     *          } string;
152     *          struct {
153     *              uint32_t tag
154     *              char     payload[];
155     *          } binary;
156     *      };
157     *  };
158     */159160header.tid = gettid();
161header.realtime.tv_sec = ts->tv_sec;
162header.realtime.tv_nsec = ts->tv_nsec;
163164newVec[0].iov_base = (unsignedchar *)&header;
165newVec[0].iov_len  = sizeof(header);
166167if (logdLoggerWrite.context.sock > 0) {
168int32_tsnapshot = atomic_exchange_explicit(&droppedSecurity, 0,
169memory_order_relaxed);
170if (snapshot) {
171android_log_event_int_tbuffer;
172173header.id = LOG_ID_SECURITY;
174buffer.header.tag = htole32(LIBLOG_LOG_TAG);
175buffer.payload.type = EVENT_TYPE_INT;
176buffer.payload.data = htole32(snapshot);
177178newVec[headerLength].iov_base = &buffer;
179newVec[headerLength].iov_len  = sizeof(buffer);
180181ret = TEMP_FAILURE_RETRY(writev(logdLoggerWrite.context.sock, newVec, 2));
182if (ret != (ssize_t)(sizeof(header) + sizeof(buffer))) {
183atomic_fetch_add_explicit(&droppedSecurity, snapshot,
184memory_order_relaxed);
185            }
186        }

查看writev的定义

/system/core/liblog/uio.c

52LIBLOG_ABI_PUBLICintwritev(intfd, conststructiovec *vecs, intcount)
53{
54inttotal = 0;
5556for ( ; count > 0; count--, vecs++ ) {
57constchar*  buf = vecs->iov_base;
58intlen = vecs->iov_len;
5960while (len > 0) {
61intret = write( fd, buf, len );
62if (ret < 0) {
63if (total == 0)
64total = -1;
65gotoExit;
66            }
67if (ret == 0)
68gotoExit;
6970total += ret;
71buf   += ret;
72len   -= ret;
73        }
74    }
75Exit:
76returntotal;
77}
78

本质上还是调用的系统write方法,向logd进行写操作

也就是说,如果给入合适的输入格式,我们是可以直接通过write操作进行写log

如:

int main(int argc, char* const argv[])

{

        int fd = open("/dev/socket/logdw", O_RDWR);

        if (fd < 0)

                aerr << "fd < 0" << endl;

        else

                aout << "fd = " << fd << endl;

 

        write(fd, "=====00 log write===============", 22);

 

 

}

 

直接这样写是有问题的,数据格式不对,

Unknown:/data/local/tmp # ./wtLog

fd < 0

这个测试需要继续研究

 

如果要正确的处理,需要再查看logd的处理方式进行分析

logd启动后的入口是/system/core/logd/main.cpp中的main方法

 

logd对log进行处理,读log是从/dev/socket/logdr来获取数据

log处理流程

Log.d() -> liblog ---socket--->logd ----socket---->logcat

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值