android 工具, 在/mnt/sdcard/log 目录下,循环记录kernel,aplog,event 一定大小的 log信息:
aplog为:总共为16*16个, 每一个log文件为1M,每满16个log文件,打包成tar 压缩包,压缩包,满足16个后,删除最老的压缩包,添加压缩生成新的压缩包
一个压缩包大小1.6M,
kernel : 同上
evetn: 一个log 大小为 500k,其余同上
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/inotify.h>
#include <unistd.h>
#include <string.h>
#include <sys/stat.h>
#include <android/log.h>
#include <fcntl.h>
#define AP_LOG_COMMOND "logcat -v threadtime -b system -b main -f /mnt/sdcard/logs/aplogcat/aplogcat -n 16 -r 1024"
#define EVENT_LOG_COMMOND "logcat -v threadtime -b events -f /mnt/sdcard/logs/event/event -n 16 -r 500 "
#define KERNEL_LOG_SIZE 1024*1024
#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "logservice", __VA_ARGS__))
#define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, "logservice", __VA_ARGS__))
#define EVENT_SIZE ( sizeof (struct inotify_event) )
#define EVENT_BUF_LEN ( 1024 * ( EVENT_SIZE + 16 ) )
#define APLOG_PATH "/mnt/sdcard/logs/aplogcat"
#define APLOG "aplogcat.01 aplogcat.02 aplogcat.03 aplogcat.04\
aplogcat.05 aplogcat.06 aplogcat.07 aplogcat.08\
aplogcat.09 aplogcat.10 aplogcat.11 aplogcat.12\
aplogcat.13 aplogcat.14 aplogcat.15 aplogcat.16"
#define EVENT_PATH "/mnt/sdcard/logs/event"
#define EVENTLOG "event.01 event.02 event.03 event.04\
event.05 event.06 event.07 event.08\
event.09 event.10 event.11 event.12\
event.13 event.14 event.15 event.16"
#define KERNEL_PATH "/mnt/sdcard/logs/kernel"
#define KERNELLOG "kernel.01 kernel.02 kernel.03 kernel.04\
kernel.05 kernel.06 kernel.07 kernel.08\
kernel.09 kernel.10 kernel.11 kernel.12\
kernel.13 kernel.14 kernel.15 kernel.16"
typedef struct entry
{
char* log;
char* key;
int value;
} AP_Entry, Event_Entry, Kernel_Entry;
static int compress_log_old(char* path, char* key, int number, char* log) {
chdir(path);
char commond[1024];
snprintf(commond, sizeof(commond), "tar -zcvf %s%02d.tar.gz %s", key, number, log);
system(commond);
snprintf(commond, sizeof(commond), "rm %s", log);
system(commond);
}
static int compress_log(char* path, char* key, int* number, char* log) {
chdir(path);
char commond[1024];
++(*number);
if((*number) > 16){
snprintf(commond, sizeof(commond), "rm -f %s%02d.tar.gz", key, --(*number));
system(commond);
}
for(int i = (*number); i > 1; i--){
snprintf(commond, sizeof(commond), "mv %s%02d.tar.gz %s%02d.tar.gz", key, (i-1), key, i);
system(commond);
}
snprintf(commond, sizeof(commond), "tar -zcvf %s01.tar.gz %s", key, log);
system(commond);
snprintf(commond, sizeof(commond), "rm %s", log);
system(commond);
}
static int watch_kernel_log(int* kernel_file_number){
if(fork() == 0 ){
system("rm -fr /mnt/sdcard/logs/kernel/kernel.*");
char commond[500];
int kmsg_fd, log_fd, log_num = 1;
void* buffer = malloc(KERNEL_LOG_SIZE/4);
int bytes_read, byte_total = 0;
kmsg_fd = open("/proc/kmsg", O_RDONLY);
log_fd = open("/mnt/sdcard/logs/kernel/kernel.01", O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR);
while(bytes_read = read(kmsg_fd, buffer, KERNEL_LOG_SIZE/4)){
if (bytes_read == -1) continue;
byte_total += bytes_read;
write(log_fd, buffer, bytes_read);
if(byte_total > KERNEL_LOG_SIZE){
if(log_num > 15){
log_num = 0;
compress_log(KERNEL_PATH, "kernel", kernel_file_number, KERNELLOG);
sleep(5);
}else{
for(int i = log_num; i > 0; i--){
snprintf(commond, sizeof(commond), "mv /mnt/sdcard/logs/kernel/kernel.%02d /mnt/sdcard/logs/kernel/kernel.%02d", i, (i+1));
system(commond);
}
}
close(log_fd);
byte_total = 0;
log_fd = open("/mnt/sdcard/logs/kernel/kernel.01", O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR);
log_num++;
}
}
free(buffer);
close(kmsg_fd);
return 1;
}
}
int main( )
{
int length, i = 0;
int fd;
int apwd, eventwd, kernelwd;
int ap_num = -1, ap_file_number = 0,
event_num = -1, event_file_number = 0,
kernel_num = -1, kernel_file_number = 0;
char buffer[EVENT_BUF_LEN];
if(access(APLOG_PATH, F_OK) == -1) {
int flag=mkdir(APLOG_PATH, 0777);
if(flag != 0){ return 1; }
}
if(access(EVENT_PATH, F_OK) == -1) {
int flag=mkdir(EVENT_PATH, 0777);
if(flag != 0){ return 1; }
}
if(access(KERNEL_PATH, F_OK) == -1) {
int flag=mkdir(KERNEL_PATH, 0777);
if(flag != 0){ return 1; }
}
//system("logcat -v threadtime -b system -b main -f /mnt/sdcard/logs/aplogcat/aplogcat -n 16 -r 1024 ");
fd = inotify_init();
if (fd < 0) {
LOGE("inotify_init failed\n");
}
apwd = inotify_add_watch(fd, APLOG_PATH, IN_CREATE );
eventwd = inotify_add_watch(fd, EVENT_PATH, IN_CREATE );
watch_kernel_log(&kernel_file_number);
if(fork() == 0 ){
LOGI("begin logcat \n");
system("rm -fr /mnt/sdcard/logs/aplogcat/aplogcat.*");
system(AP_LOG_COMMOND);
LOGI("end logcat \n");
return 1;
}
if(fork() == 0 ){
LOGI("begin event \n");
system("rm -fr /mnt/sdcard/logs/event/event.*");
system(EVENT_LOG_COMMOND);
LOGI("end event \n");
return 1;
}
for ( ; ;)
{
i = 0;
length = read(fd, buffer, EVENT_BUF_LEN);
if (length < 0) {
LOGE("read failed length is %d,\n", length);
continue;
}
while (i < length) {
struct inotify_event *event = (struct inotify_event *) &buffer[i];
if (event->len) {
if (event->mask & IN_CREATE) {
if(strcmp(event->name, "aplogcat") == 0){
ap_num++;
if(ap_num > 15){
//ap_file_number++;
compress_log(APLOG_PATH, event->name, &ap_file_number, APLOG);
ap_num = 0;
}
//if(ap_file_number > 15) ap_file_number = 0;
}else if(strcmp(event->name, "event") == 0){
event_num++;
if(event_num > 15){
//event_file_number++;
compress_log(EVENT_PATH, event->name, &event_file_number, EVENTLOG);
event_num = -1;
}
//if(event_file_number > 15) event_file_number = 0;
}
}
}
//TODO delete old log
i += EVENT_SIZE + event->len;
}
}
inotify_rm_watch(fd, apwd);
//inotify_rm_watch(fd, eventwd);
//inotify_rm_watch(fd, kernelwd);
close(fd);
return 0;
}
对应android.mk 为:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := logservice
LOCAL_SRC_FILES := logservice.c++
LOCAL_LDLIBS := -llog -landroid
include $(BUILD_EXECUTABLE)