logger

logger.h
#ifndef _LOGGER
#define _LOGGER
#include <stdio.h>
#ifdef __cplusplus
extern "C"
{
#endif
//#include <stdarg.h>
#define log sys_log
#define log_err(fmt,...) sys_log(1,fmt,## __VA_ARGS__)
//#define log_err(fmt,args...) sys_log(1,fmt,args)
void init_log(int level);
void release_log();
void sys_log(int,const char*,...);
struct sys_logger{
        char* file_name;
	char* file_path;
        int fd[2];
		FILE *stream[2];
};
#ifdef __cplusplus
}
#endif
#endif</stdarg></stdio>

logger.c

#include <stdlib.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <stdarg.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <errno.h>
#include "logger.h"
static int log_level = 2;
struct sys_logger sys = {"sys","./log",{0,0},{NULL,NULL}};
void sys_log(int level,const char* fmt,...){
          if(level > log_level)
                  return;//cancel the log ,return
          va_list va;
          va_start(va,fmt);//get variable parameters
  
          time_t now;
          time(&now);
          struct tm *timenow = localtime(&now);
		  if(NULL == sys.stream[1]){
		  printf("Log FILE stream NULL");
          char buf[4096]={0};//buffer
		  int bytes = snprintf(buf,sizeof buf,"%d-%02d-%02d %02d:%02d:%02d ",(1900+timenow->tm_year),(1+timenow->tm_mon),timenow->tm_mday,timenow->tm_hour,timenow->tm_min,timenow->tm_sec);
          //format the content to the buffer
          bytes += vsnprintf(buf + bytes,sizeof(buf) - bytes,fmt,va);
          while(bytes > 0){
				int wbytes = write(sys.fd[1],buf,strlen(buf));
                  //printf("write %d bytes,content:%s\n",wbytes,buf);
				  if(wbytes == -1 && errno != EAGAIN)
                          break;
                  bytes -= wbytes;
          }
		  }else{
			  char fmt_buf[1024] ={0};
			  const char* const_fmt = fmt_buf;
				sprintf(fmt_buf,"%d-%02d-%02d %02d:%02d:%02d %s",(1900+timenow->tm_year),(1+timenow->tm_mon),timenow->tm_mday,timenow->tm_hour,timenow->tm_min,timenow->tm_sec,fmt);
				printf("%d",timenow->tm_year);
				vfprintf(sys.stream[1],const_fmt,va);
		  }
          va_end(va);
  }
  
 void get_log(void* fd){
		  FILE* fs = NULL;
          time_t now;
          time(&now);
          struct tm *p = localtime(&now);
          char file_name_buf[1024]={0};
          //format the file name
          snprintf(file_name_buf,1024
                  ,sys.file_path[strlen(sys.file_path) - 1] == '/'?
                  "%s%d%02d%02d-%s":"%s/%d%02d%02d-%s"
                  ,sys.file_path, (1900+p->tm_year),(1+p->tm_mon), p->tm_mday,sys.file_name);
	
          if(mkdir(sys.file_path,S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) == -1 && errno != EEXIST){
                  printf("create log directory error.errno=%d.%s",errno,strerror(errno));
                  return ;
          }
          //Open for appending (writing at end of file).   The  file  is
          //created  if  it does not exist.  The stream is positioned at
          //the end of the file.
          fs = fopen(file_name_buf,"a");
          if(NULL == fs)
                  printf("log file %s open error.errno=%d,%s\n",file_name_buf,errno,strerror(errno));
          else{
				setvbuf(fs, (char *)NULL, _IOLBF, 0);
                char new_file_name_buf[1024];
                while(1){
                        memset(new_file_name_buf,0,sizeof new_file_name_buf);
                        time(&now);
                        p = localtime(&now);
                        //format the file name
                        snprintf(new_file_name_buf,1024
                                ,sys.file_path[strlen(sys.file_path) - 1] == '/'?
                                "%s%d%02d%02d-%s":"%s/%d%02d%02d-%s"
                                ,sys.file_path, (1900+p->tm_year),(1+p->tm_mon)
                                , p->tm_mday,sys.file_name);
                        if(strcmp(new_file_name_buf,file_name_buf) != 0){
                                fclose(fs);
                                fs = fopen(new_file_name_buf,"a");
                                if(NULL == fs){
                                        printf("open new log file %s error.errno=%d,%s\n"
                                                ,new_file_name_buf,errno,strerror(errno));
                                        break;
                                }
								setvbuf(fs, (char *)NULL, _IOLBF, 0);
                        }else{
                                memset(file_name_buf,0,sizeof file_name_buf);//file
                                memcpy(file_name_buf,new_file_name_buf,strlen(new_file_name_buf));
;
                                //read pipe
                                char buf[4096] = {0};
                                //printf("reading ...\n");
                                if(read(sys.fd[0],buf,sizeof(buf) - 1) <= 0)
                                        if(errno != EAGAIN || errno != EINTR)
                                                break;
                                fwrite(buf,strlen(buf),1,fs);
                        }
                }
                //printf("while out...\n");
                fclose(fs);
		}
}

static void write_log(){

}

///initialize log processes
void init_log(int level)
{
		log_level = level;
        if(pipe(sys.fd) == -1){
                printf("pipe for sys log error errno=%d,%s\n"
                        ,errno,strerror(errno));
        }
        else{
                pid_t pid;
                pid = fork();
                if(0 == pid)
                {
						printf("Log process run.\n");
                        ///do the work..
                        pthread_t id1,id2;
                        close(sys.fd[1]);//close write
						//if(NULL != sys.stream[1])
						//	fclose(sys.stream[1]);
						//sys.stream[0] = fdopen(sys.fd[0],"a");
						
						pthread_create(&id1,NULL,(void*(*)(void*))get_log,NULL);
                        pthread_join(id1,NULL);
                        //pthread_join(id2,NULL);
                        close(sys.fd[0]);//close read
						//if(NULL != sys.stream[0])
						//	fclose(sys.stream[0]);
                        //printf("log process exit...\n");
                        exit(0);//child exit
                }else if(pid < 0)///error
                        {
							printf("fork error.errno=%d,%s\n",errno,strerror(errno));
						}
				else
						{close(sys.fd[0]);
						
						sys.stream[1] = fdopen(sys.fd[1],"a");
						if(NULL == sys.stream[1])
						{
						printf("open FILE stream error,using buffer to write log,may be some data will lost.errno=%d [%s]\n",errno,strerror(errno));
							}
						}
	}
}

void release_log(){
	sys_log(1,"%s","<exit>");
	close(sys.fd[1]);
	if(NULL != sys.stream[1])
		fclose(sys.stream[1]);
	//int childs,countchild;
	//while(1){
	printf("waiting for child exit...\n");
		wait(NULL);
		//if(++countchild >= childs)
			//break;
	//}
}

</exit></errno></unistd></time></string></stdarg></sys></sys></sys></pthread></stdlib>

testlogger.c

 
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include "logger.h"
//extern int log_level;
int main(int argc,char** argv){
        if(argc > 1)
                sscanf(argv[1],"%d",&log_level);
        pid_t pa,pb;
        int count = 0;
        init_log(1);
        char *a = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n";
        char *b = "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n";
        char *c = "cccccccccccccccccccccccccccccccc\n";
        if((pa = fork()) == 0){
                while(count < 5){
                        sys_log(1,"%s",a);
                        //usleep(1000);
                        ++count;
                }
                exit(1);
        }
        else{
                if((pb = fork()) == 0){
                        while(count < 5){
                                sys_log(2,"%s",b);
                                //usleep(1000);
                                ++count;
                        }
                        exit(1);
                }
        }
        while(count < 5){
                log(3,"%s",c);
                //usleep(1000);
                ++count;
        }
        //sys_log(1,"%s","<exit>");

        //int status;
        //waitpid(pa,&status,WEXITSTATUS);
        //waitpid(pb,&status,WEXITSTATUS);
        release_log();
        printf("main process exit.\n");
        return 0;
}


with extern "C"{}

[l@localhost code]$g++ -g -lpthread logger.c logger.h testlogger.c -o logger.exe
[l@localhost code]$ objdump --syms logger.exe 


logger.exe:     file format elf64-x86-64


SYMBOL TABLE:
0000000000400200 l    d  .interp	0000000000000000              .interp
000000000040021c l    d  .note.ABI-tag	0000000000000000              .note.ABI-tag
0000000000400240 l    d  .gnu.hash	0000000000000000              .gnu.hash
0000000000400268 l    d  .dynsym	0000000000000000              .dynsym
0000000000400520 l    d  .dynstr	0000000000000000              .dynstr
000000000040065a l    d  .gnu.version	0000000000000000              .gnu.version
0000000000400698 l    d  .gnu.version_r	0000000000000000              .gnu.version_r
00000000004006f8 l    d  .rela.dyn	0000000000000000              .rela.dyn
0000000000400710 l    d  .rela.plt	0000000000000000              .rela.plt
0000000000400980 l    d  .init	0000000000000000              .init
0000000000400998 l    d  .plt	0000000000000000              .plt
0000000000400b50 l    d  .text	0000000000000000              .text
0000000000401618 l    d  .fini	0000000000000000              .fini
0000000000401628 l    d  .rodata	0000000000000000              .rodata
0000000000401818 l    d  .eh_frame_hdr	0000000000000000              .eh_frame_hdr
0000000000401860 l    d  .eh_frame	0000000000000000              .eh_frame
0000000000601980 l    d  .ctors	0000000000000000              .ctors
0000000000601990 l    d  .dtors	0000000000000000              .dtors
00000000006019a0 l    d  .jcr	0000000000000000              .jcr
00000000006019a8 l    d  .dynamic	0000000000000000              .dynamic
0000000000601b78 l    d  .got	0000000000000000              .got
0000000000601b80 l    d  .got.plt	0000000000000000              .got.plt
0000000000601c70 l    d  .data	0000000000000000              .data
0000000000601ca8 l    d  .bss	0000000000000000              .bss
0000000000000000 l    d  .comment	0000000000000000              .comment
0000000000000000 l    d  .debug_aranges	0000000000000000              .debug_aranges
0000000000000000 l    d  .debug_pubnames	0000000000000000              .debug_pubnames
0000000000000000 l    d  .debug_info	0000000000000000              .debug_info
0000000000000000 l    d  .debug_abbrev	0000000000000000              .debug_abbrev
0000000000000000 l    d  .debug_line	0000000000000000              .debug_line
0000000000000000 l    d  .debug_frame	0000000000000000              .debug_frame
0000000000000000 l    d  .debug_str	0000000000000000              .debug_str
0000000000000000 l    d  .debug_loc	0000000000000000              .debug_loc
0000000000400b7c l     F .text	0000000000000000              call_gmon_start
0000000000000000 l    df *ABS*	0000000000000000              crtstuff.c
0000000000601980 l     O .ctors	0000000000000000              __CTOR_LIST__
0000000000601990 l     O .dtors	0000000000000000              __DTOR_LIST__
00000000006019a0 l     O .jcr	0000000000000000              __JCR_LIST__
0000000000601ca8 l     O .bss	0000000000000008              dtor_idx.6147
0000000000601cb0 l     O .bss	0000000000000001              completed.6145
0000000000400ba0 l     F .text	0000000000000000              __do_global_dtors_aux
0000000000400c00 l     F .text	0000000000000000              frame_dummy
0000000000000000 l    df *ABS*	0000000000000000              crtstuff.c
0000000000601988 l     O .ctors	0000000000000000              __CTOR_END__
0000000000401978 l     O .eh_frame	0000000000000000              __FRAME_END__
00000000006019a0 l     O .jcr	0000000000000000              __JCR_END__
00000000004015e0 l     F .text	0000000000000000              __do_global_ctors_aux
0000000000000000 l    df *ABS*	0000000000000000              logger.c
0000000000000000 l    df *ABS*	0000000000000000              testlogger.c
000000000060197c l       .ctors	0000000000000000              .hidden __preinit_array_start
000000000060197c l       .ctors	0000000000000000              .hidden __fini_array_end
0000000000601b80 l     O .got.plt	0000000000000000              .hidden _GLOBAL_OFFSET_TABLE_
000000000060197c l       .ctors	0000000000000000              .hidden __preinit_array_end
000000000060197c l       .ctors	0000000000000000              .hidden __fini_array_start
000000000060197c l       .ctors	0000000000000000              .hidden __init_array_end
000000000060197c l       .ctors	0000000000000000              .hidden __init_array_start
00000000006019a8 l     O .dynamic	0000000000000000              .hidden _DYNAMIC
0000000000601c70  w      .data	0000000000000000              data_start
0000000000000000       F *UND*	00000000000000a2              printf@@GLIBC_2.2.5
0000000000000000       F *UND*	0000000000000b1b              memset@@GLIBC_2.2.5
0000000000401540 g     F .text	0000000000000002              __libc_csu_fini
0000000000000000       F *UND*	000000000000008b              snprintf@@GLIBC_2.2.5
0000000000400b50 g     F .text	0000000000000000              _start
0000000000000000       F *UND*	000000000000006c              close@@GLIBC_2.2.5
0000000000000000       F *UND*	000000000000008e              wait@@GLIBC_2.2.5
0000000000000000  w      *UND*	0000000000000000              __gmon_start__
0000000000000000  w      *UND*	0000000000000000              _Jv_RegisterClasses
0000000000000000       F *UND*	000000000000018c              puts@@GLIBC_2.2.5
0000000000000000       F *UND*	00000000000000f1              exit@@GLIBC_2.2.5
0000000000401618 g     F .fini	0000000000000000              _fini
0000000000000000       F *UND*	0000000000000080              read@@GLIBC_2.2.5
0000000000000000       F *UND*	000000000000000a              fopen@@GLIBC_2.2.5
0000000000000000       F *UND*	00000000000001a5              __libc_start_main@@GLIBC_2.2.5
0000000000400d12 g     F .text	0000000000000494              _Z7get_logPv
0000000000401628 g     O .rodata	0000000000000004              _IO_stdin_used
0000000000601c70 g       .data	0000000000000000              __data_start
0000000000000000       F *UND*	0000000000000c5f              pthread_create@@GLIBC_2.2.5
0000000000000000       F *UND*	0000000000000090              sscanf@@GLIBC_2.2.5
0000000000000000       F *UND*	0000000000000025              pipe@@GLIBC_2.2.5
0000000000000000       F *UND*	0000000000000160              pthread_join@@GLIBC_2.2.5
0000000000000000       F *UND*	00000000000000b9              strerror@@GLIBC_2.2.5
0000000000400c28 g     F .text	00000000000000ea              init_log
00000000004013e4 g     F .text	000000000000003e              release_log
0000000000401630 g     O .rodata	0000000000000000              .hidden __dso_handle
0000000000601c90 g     O .data	0000000000000018              sys
0000000000601998 g     O .dtors	0000000000000000              .hidden __DTOR_END__
0000000000401550 g     F .text	000000000000008b              __libc_csu_init
0000000000601c80 g     O .data	0000000000000004              log_level
0000000000000000       F *UND*	00000000000000e4              vsnprintf@@GLIBC_2.2.5
0000000000000000       F *UND*	0000000000000011              __errno_location@@GLIBC_2.2.5
0000000000601ca8 g       *ABS*	0000000000000000              __bss_start
0000000000000000       F *UND*	0000000000000021              strcmp@@GLIBC_2.2.5
0000000000601cb8 g       *ABS*	0000000000000000              _end
0000000000000000       F *UND*	0000000000000206              fclose@@GLIBC_2.2.5
00000000004011a6 g     F .text	000000000000023d              sys_log
0000000000000000       F *UND*	0000000000000005              fork@@GLIBC_2.2.5
0000000000000000       F *UND*	0000000000000163              fwrite@@GLIBC_2.2.5
0000000000601ca8 g       *ABS*	0000000000000000              _edata
0000000000400af8       F *UND*	00000000000004bf              __gxx_personality_v0@@CXXABI_1.3
0000000000000000       F *UND*	0000000000000011              localtime@@GLIBC_2.2.5
0000000000000000       F *UND*	0000000000000080              write@@GLIBC_2.2.5
0000000000000000       F *UND*	0000000000000025              mkdir@@GLIBC_2.2.5
0000000000000000       F *UND*	0000000000000012              time@@GLIBC_2.2.5
0000000000401424 g     F .text	0000000000000112              main
0000000000400980 g     F .init	0000000000000000              _init


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值