跟我写ANYDUL之 Anydul Log SImple Log Utility Implement
1. Every Project owns it's log utility tool(for example Nginx), the same as ANYDUL, this section I will introduce Anydul Simple log utility implement. (Note: these papers about ANYDUL implement can help u guys to learn C programming and Oracle Database although I'm also learning how to write code now.)
2. There are two features in this simple log utility. One is a buffer sized with 2048, So it can reduce output operations; the second it flushes every 2 seconds by registering alarm signal.
3. Source Code.
3.1 klog.h
[billi@slc04kwh kernel]$ cat klog.h
/*
* =====================================================================================
* Copyright (c) 2013, Bin Li, Anydul
*
* Filename: klog.h
* Description: Kernel Log Utility Header
*
* Version: 1.0
* Revision: none
* Author: Bin Li (billi) billi.x.lee@gmail.com
* Organization: Anydul, Inc.
*
* Modified: (MM/DD/YY)
*
* Bin Li 05/27/13 - Creation
*
* =====================================================================================
*/
#ifndef _KLOG_H
#define _KLOG_H
#include <ks.h>
#define KLOG_BUFSIZE 2048
typedef struct _klog klog;
struct _klog
{
FILE* file; //log file pointer
sb1* buf; //log buffer
ub4 len; //current length of log buffer
};
/*-----------------------------------------------------------------------------
* kernel log utility initialize and destory funtions
* klog_init -> initialize log utility
* klog_free -> destroy log utility
*-----------------------------------------------------------------------------*/
klog* klog_init(const sb1* name);
void klog_free();
/*-----------------------------------------------------------------------------
* kernel log utility operation functions
* klog_write -> write message to log buffer
* klog_flush -> flush log buffer
* klog_close -> close log utility
*-----------------------------------------------------------------------------*/
void klog_write(klog* log, const sb1* fmt, ...);
void klog_flush(klog* log);
void klog_close(klog* log);
#endif
3.2 klog.c
[billi@slc04kwh kernel]$ cat klog.c
/*
* =====================================================================================
* Copyright (c) 2013, Bin Li, Anydul
*
*
* # # # # # # # # # #
* # # # # # # # # # # # #
* # # # # # # # # # # # #
* # # # # # # # # # # # #
* # # # # # # # # # # # # # # #
*
*
* Filename: klog.c
* Description: Kernel Log Utility Implement
*
* Version: 1.0
* Revision: none
* Compiler: gcc
* Author: Bin Li (billi), billi.x.lee@gmail.com
* Organization: Anydul, Inc.
*
* Modified: (MM/DD/YY)
*
* Bin Li 05/27/13 - Creation
*
* =====================================================================================
*/
#include <klog.h>
static klog syslog; /* system log utility */
/*-----------------------------------------------------------------------------
* log utility functions
* timestamp -> get current timestapm
* signal_flush -> register signal for flush system log every 2 seconds
*-----------------------------------------------------------------------------*/
static ub4 timestamp(sb1* buf);
static void signal_flush(int signo);
/*
* === FUNCTION ======================================================================
* Name: klog_init
* Description:
* =====================================================================================
*/
klog* klog_init(const sb1* name)
{
FILE* f;
syslog.buf = calloc(KLOG_BUFSIZE, sizeof(sb1));
if(NULL == syslog.buf)
{
return NULL; //if allocate memory failed for log buffer, return NULL
}
f = fopen(name, "w");
if(NULL == f)
{
syslog.file = stdout; //set it to console if can't open given name
}
else
{
syslog.file = f;
}
syslog.len = 0;
signal(SIGALRM, signal_flush); //register flush functions
alarm(2);
return &syslog;
}
/*
* === FUNCTION ======================================================================
* Name: klog_free
* Description:
* =====================================================================================
*/
void klog_free()
{
klog_close(&syslog); // close system log
free(syslog.buf); // free log buffer
}
/*
* === FUNCTION ======================================================================
* Name: klog_write
* Description:
* =====================================================================================
*/
void klog_write(klog* log, const sb1* fmt, ...)
{
sb1 buf[KLOG_BUFSIZE];
va_list args;
ub4 s = 0, len = 0;
memset(buf, 0x00, KLOG_BUFSIZE);
if(log == &syslog){
s = timestamp(buf);
}
va_start(args, fmt);
len = vsnprintf(buf + s, KLOG_BUFSIZE - 1, fmt, args);
va_end(args);
if(s + len + log->len >= KLOG_BUFSIZE - 1){
klog_flush(log);
}
memcpy(log->buf + log->len, buf, strlen(buf));
log->len += len + s;
}
/*
* === FUNCTION ======================================================================
* Name: klog_flush
* Description:
* =====================================================================================
*/
void klog_flush(klog* log)
{
if(log->len > 0){
fprintf(log->file, "%s", log->buf);
fflush(log->file);
log->len = 0;
memset(log->buf, 0x00, KLOG_BUFSIZE);
}
}
/*
* === FUNCTION ======================================================================
* Name: klog_close
* Description:
* =====================================================================================
*/
void klog_close(klog* log)
{
klog_flush(log);
if(log->file != NULL && log->file != stdout)
{
fclose(log->file);
}
}
static ub4 timestamp(sb1* buf)
{
time_t t;
ub4 len;
struct tm* now;
t = time(NULL);
now = localtime(&t);
len = snprintf(buf, KLOG_BUFSIZE - 1, "[%d-%02d-%02d %02d:%02d:%02d] ", now->tm_year + 1900, now->tm_mon + 1, now->tm_mday, now->tm_hour, now->tm_min, now->tm_sec);
return len;
}
static void signal_flush(int sig)
{
printf("alarm flush start...\n");
klog_flush(&syslog);
alarm(2);
return;
}
3.3 test case: klog_test.c
/*
* =====================================================================================
* Copyright (c) 2013, Bin Li, Anydul
*
*
* # # # # # # # # # #
* # # # # # # # # # # # #
* # # # # # # # # # # # #
* # # # # # # # # # # # #
* # # # # # # # # # # # # # # #
*
*
* Filename: klog_test.c
* Description:
*
* Version: 1.0
* Revision: none
* Compiler: gcc
* Author: Bin Li (billi), billi.x.lee@gmail.com
* Organization: Anydul, Inc.
*
* Modified: (MM/DD/YY)
*
* Bin Li 05/21/13 - Creation
*
* =====================================================================================
*/
#include <klog.h>
#include <stdlib.h>
#include <stdio.h>
/*
* === FUNCTION ======================================================================
* Name: main
* Description:
* =====================================================================================
*/
int main ( int argc, char *argv[] )
{
const sb1* str = "testcase.sh";
FILE* f = fopen(str,"r");
sb1 buf[1024];
if(NULL == f)
{
return 1;
}
klog *log = klog_init("klog_test.log");
if(NULL == log)
{
fclose(f);
return 1;
}
sb1* ptr = NULL;
while((ptr = fgets(buf, 1023, f)) != NULL)
{
klog_write(log, "%s", ptr);
sleep(1);
}
fclose(f);
klog_free();
return EXIT_SUCCESS;
} /* ---------- end of function main ---------- */
4. Run test case
4.1 test case framework
[billi@slc04kwh test]$ tree
.
|-- Makefile
|-- core
|-- kernel
| `-- klog_test.c
|-- net
|-- os
|-- sql
`-- testcase.sh
5 directories, 3 files
4.2 Run test case
gcc -O3 -Wall -c -fmessage-length=0 ../source/kernel/*.c -I. -I../source/core -I../source/kernel -I../source/net/
ar rcs libanydul.a *.o
rm -rf *.o
gcc -O3 -Wall -c -fmessage-length=0 kernel/*.c -I. -I../source/core -I../source/kernel -I../source/net/
./testcase.sh
[********** Run Test Cases For Module core **********]
There is none test case now...
[********** Run Test Cases For Module kernel **********]
alarm flush start...
alarm flush start...
alarm flush start...
alarm flush start...
alarm flush start...
alarm flush start...
alarm flush start...
alarm flush start...
alarm flush start...
alarm flush start...
alarm flush start...
alarm flush start...
alarm flush start...
alarm flush start...
alarm flush start...
alarm flush start...
alarm flush start...
Run Test Case klog_test
[********** Run Test Cases For Module net **********]
There is none test case now...
[********** Run Test Cases For Module os **********]
There is none test case now...
[********** Run Test Cases For Module sql **********]
There is none test case now...
rm -rf *.o
5. klog_test.log
[2013-05-27 07:20:39] #!/bin/bash
[2013-05-27 07:20:40]
[2013-05-27 07:20:41] curdir=`dirname $0`
[2013-05-27 07:20:42] curdir=`cd $curdir; pwd`
[2013-05-27 07:20:43]
[2013-05-27 07:20:44] # Make all test cases
[2013-05-27 07:20:45] #make -f Makefile
[2013-05-27 07:20:46]
[2013-05-27 07:20:47] modules=`ls $curdir`
[2013-05-27 07:20:48]
[2013-05-27 07:20:49] for module in $modules
[2013-05-27 07:20:50] do
[2013-05-27 07:20:51] if [ -d "$curdir/$module" ]; then
[2013-05-27 07:20:52] echo "[********** Run Test Cases For Module $module **********]"
[2013-05-27 07:20:53] testes=`ls $curdir/$module`
[2013-05-27 07:20:54]
[2013-05-27 07:20:55] if [ -z "$testes" ]; then
[2013-05-27 07:20:56] echo " There is none test case now..."
[2013-05-27 07:20:57] continue;
[2013-05-27 07:20:58] fi
[2013-05-27 07:20:59]
[2013-05-27 07:21:00] for test in $testes
[2013-05-27 07:21:01] do
[2013-05-27 07:21:02] name=`echo $test | sed 's/\.c//g'`
[2013-05-27 07:21:03] gcc -g -o $curdir/$name $curdir/${name}.o -L$curdir -lanydul
[2013-05-27 07:21:04] $curdir/$name
[2013-05-27 07:21:05] echo ""
[2013-05-27 07:21:06] echo " Run Test Case $name"
[2013-05-27 07:21:07] echo ""
[2013-05-27 07:21:08] if [ -f "$curdir/$name" ]; then
[2013-05-27 07:21:09] rm -rf $curdir/$name $curdir/${name}.o
[2013-05-27 07:21:10] fi
[2013-05-27 07:21:11] done
[2013-05-27 07:21:12] fi
[2013-05-27 07:21:13] done
/*
* =====================================================================================
* Copyright (c) 2013, Bin Li, Anydul
*
* Filename: ks.h
* Description: Kernel System Header
*
* Version: 1.0
* Revision: none
* Author: Bin Li (billi) billi.x.lee@gmail.com
* Organization: Anydul, Inc.
*
* Modified: (MM/DD/YY)
*
* Bin Li 05/27/13 - Support Linux System
* Bin Li 05/27/13 - Creation
*
* =====================================================================================
*/
#ifndef _KS_H
#define _KS_H
/* Import Standard C Header File */
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <stdint.h>
#include <string.h>
#include <stddef.h>
#include <stdarg.h>
#include <unistd.h>
#include <signal.h>
#include <time.h>
#ifndef ORATYPES
/* Kernel Variable Type Define */
typedef char sb1;
typedef short sb2;
typedef int sb4;
typedef long long sb8;
typedef unsigned char ub1;
typedef unsigned short ub2;
typedef unsigned int ub4;
typedef unsigned long long ub8;
typedef int boolean;
typedef char bool;
#endif
#define TRUE 1
#define FALSE 0
#define min(a, b) ((a) < (b) ? (a) : (b))
#define bit(var, bit) ((var) & (bit) ? TRUE : FALSE)
#define bit_set(var, bit) (var |= bit)
#define bit_clear(var, bit) (var &= ~(bit))
#define offset(s, m) (size_t)&(((s*)0)->m)
#endif
Continue next section kmm kernel memory manage module....