C语言日志库lagan

C语言日志库lagan

本文博客链接:http://blog.csdn.net/jdh99,作者:jdh,转载请注明.

介绍

lagan是C语言日志库,取名来自于宜家的水龙头"拉根"。

本包是golang编写的lagan的C语言移植版本:go语言日志库lagan

开源

功能

  • 支持日志在终端实时打印
  • 支持二进制流打印

API

// 日志级别
typedef enum {
    LAGAN_LEVEL_OFF = 0,
    LAGAN_LEVEL_DEBUG,
    LAGAN_LEVEL_INFO,
    LAGAN_LEVEL_WARN,
    LAGAN_LEVEL_ERROR
} LaganLevel;

// 模块名最大长度
#define LAGAN_MODULE_NAME_LEN_MAX 100

// 默认的日志记录最大字节数
#define LAGAN_RECORD_MAX_SIZE_DEFAULT 512

// 默认过滤级别
#define LAGAN_FILTER_LEVEL_DEAFULT LAGAN_LEVEL_DEBUG

#define LD(tag, format, ...) LaganPrint(tag, LAGAN_LEVEL_DEBUG, format, ##__VA_ARGS__)
#define LI(tag, format, ...) LaganPrint(tag, LAGAN_LEVEL_INFO, format, ##__VA_ARGS__)
#define LW(tag, format, ...) LaganPrint(tag, LAGAN_LEVEL_WARN, format, ##__VA_ARGS__)
#define LE(tag, format, ...) LaganPrint(tag, LAGAN_LEVEL_ERROR, format, ##__VA_ARGS__)

#pragma pack(1)

// 读取时间.24小时制
typedef struct {
    // 年是4位数,格式如2020
    int Year;
    int Month;
    int Day;
    int Hour;
    int Minute;
    int Second;
    int Us;
} LaganTime;

#pragma pack()

// LaganPrintFunc 打印数据类型
typedef void (*LaganPrintFunc)(uint8_t* bytes, int size);

// LaganTime 读取时间
typedef LaganTime (*LaganGetTimeFunc)(void);

// LaganLoad 模块载入
void LaganLoad(LaganPrintFunc print, LaganGetTimeFunc getTime);

// LaganSetFilterLevel 设置过滤日志等级
void LaganSetFilterLevel(LaganLevel level);

// PaxGetFilterLevel 显示过滤日志等级
LaganLevel LaganGetFilterLevel(void);

// LaganPrint 日志打印
void LaganPrint(char* tag, LaganLevel level, char *format, ...);

// LaganPrintHex 打印字节流
void LaganPrintHex(char* tag, LaganLevel level, uint8_t* bytes, int size);

// PaxPause 暂停日志打印
void LaganPause(void);

// PaxResume 恢复日志打印
void LaganResume(void);

// PaxIsPause 是否暂停
bool LaganIsPause(void);

测试

#include <QCoreApplication>
#include <QDateTime>

extern "C" {
    #include "lagan.h"
}

static void print(uint8_t* bytes, int size);
static LaganTime getTime(void);

static void case1(void);
static void case2(void);
static void case3(void);

int main(int argc, char *argv[]) {
    QCoreApplication a(argc, argv);

    LaganLoad(print, getTime);

    case1();
    case2();
    case3();

    return a.exec();
}

static void print(uint8_t* bytes, int size) {
    printf("%s", bytes);
}

static LaganTime getTime(void) {
    QDate date = QDateTime::currentDateTime().date();
    QTime now = QTime::currentTime();

    LaganTime time;
    time.Year = date.year();
    time.Month = date.month();
    time.Day = date.day();
    time.Hour = now.hour();
    time.Minute = now.minute();
    time.Second = now.second();
    time.Us = now.msec() * 1000;
    return time;
}

static void case1(void) {
    LD("case1", "debug test print:%d", 1);
    LI("case1", "info test print:%d", 2);
    LW("case1", "warn test print:%d", 3);
    LE("case1", "error test print:%d", 4);
}

static void case2(void) {
    LaganSetFilterLevel(LAGAN_LEVEL_WARN);
    // 过滤不会打印
    LD("case2", "debug test print:%d", 1);
    // 过滤不会打印
    LI("case2", "info test print:%d", 2);

    LW("case2", "warn test print:%d", 3);
    LE("case2", "error test print:%d", 4);
}

static void case3(void) {
    LaganSetFilterLevel(LAGAN_LEVEL_DEBUG);
    uint8_t arr[100] = {0};
    for (int i = 0; i < 100; i++) {
        arr[i] = (uint8_t)i;
    }

    LI("case3", "print hex");
    LaganPrintHex("case3", LAGAN_LEVEL_INFO, arr, 100);
}

输出:

2021/04/12 06:37:06.583000 D/case1 debug test print:1
2021/04/12 06:37:06.588000 I/case1 info test print:2
2021/04/12 06:37:06.592000 W/case1 warn test print:3
2021/04/12 06:37:06.596000 E/case1 error test print:4
2021/04/12 06:37:06.603000 W/case2 warn test print:3
2021/04/12 06:37:06.606000 E/case2 error test print:4
2021/04/12 06:37:06.611000 I/case3 print hex
2021/04/12 06:37:06.632000 I/case3
00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f
10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f
20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f
30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f
40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f
50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f
60 61 62 63

源码

最新源码请查看github或者gitee仓库。

lagan.h

// Copyright 2020-2021 The jdh99 Authors. All rights reserved.
// 实时流日志库.可以用于串口等流日志打印
// Authors: jdh99 <jdh821@163.com>
// lagan取名来自于宜家的水龙头"拉根"

#ifndef LAGAN_H
#define LAGAN_H

#include <stdint.h>
#include <stdbool.h>

// 日志级别
typedef enum {
    LAGAN_LEVEL_OFF = 0,
    LAGAN_LEVEL_DEBUG,
    LAGAN_LEVEL_INFO,
    LAGAN_LEVEL_WARN,
    LAGAN_LEVEL_ERROR
} LaganLevel;

// 模块名最大长度
#define LAGAN_MODULE_NAME_LEN_MAX 100

// 默认的日志记录最大字节数
#define LAGAN_RECORD_MAX_SIZE_DEFAULT 512

// 默认过滤级别
#define LAGAN_FILTER_LEVEL_DEAFULT LAGAN_LEVEL_DEBUG

#define LD(tag, format, ...) LaganPrint(tag, LAGAN_LEVEL_DEBUG, format, ##__VA_ARGS__)
#define LI(tag, format, ...) LaganPrint(tag, LAGAN_LEVEL_INFO, format, ##__VA_ARGS__)
#define LW(tag, format, ...) LaganPrint(tag, LAGAN_LEVEL_WARN, format, ##__VA_ARGS__)
#define LE(tag, format, ...) LaganPrint(tag, LAGAN_LEVEL_ERROR, format, ##__VA_ARGS__)

#pragma pack(1)

// 读取时间.24小时制
typedef struct {
    // 年是4位数,格式如2020
    int Year;
    int Month;
    int Day;
    int Hour;
    int Minute;
    int Second;
    int Us;
} LaganTime;

#pragma pack()

// LaganPrintFunc 打印数据类型
typedef void (*LaganPrintFunc)(uint8_t* bytes, int size);

// LaganTime 读取时间
typedef LaganTime (*LaganGetTimeFunc)(void);

// LaganLoad 模块载入
void LaganLoad(LaganPrintFunc print, LaganGetTimeFunc getTime);

// LaganSetFilterLevel 设置过滤日志等级
void LaganSetFilterLevel(LaganLevel level);

// PaxGetFilterLevel 显示过滤日志等级
LaganLevel LaganGetFilterLevel(void);

// LaganPrint 日志打印
void LaganPrint(char* tag, LaganLevel level, char *format, ...);

// LaganPrintHex 打印字节流
void LaganPrintHex(char* tag, LaganLevel level, uint8_t* bytes, int size);

// PaxPause 暂停日志打印
void LaganPause(void);

// PaxResume 恢复日志打印
void LaganResume(void);

// PaxIsPause 是否暂停
bool LaganIsPause(void);

#endif

lagan.c

// Copyright 2020-2021 The jdh99 Authors. All rights reserved.
// 实时流日志库.可以用于串口等流日志打印
// Authors: jdh99 <jdh821@163.com>
// lagan取名来自于宜家的水龙头"拉根"

#include "lagan.h"
#include <stdio.h>
#include <stdarg.h>
#include <string.h>

static bool gIsPause = false;
static LaganLevel gFilterLevel = LAGAN_FILTER_LEVEL_DEAFULT;
static char gLevelCh[] = {'O', 'D', 'I', 'W', 'E'};

static LaganPrintFunc gOutput = NULL;
static LaganGetTimeFunc gGetTime = NULL;

// LaganLoad 模块载入
void LaganLoad(LaganPrintFunc print, LaganGetTimeFunc getTime) {
    gOutput = print;
    gGetTime = getTime;
}

// LaganSetFilterLevel 设置过滤日志等级
void LaganSetFilterLevel(LaganLevel level) {
    gFilterLevel = level;
}

// PaxGetFilterLevel 显示过滤日志等级
LaganLevel LaganGetFilterLevel(void) {
    return gFilterLevel;
}

// LaganPrint 日志打印
void LaganPrint(char* tag, LaganLevel level, char *format, ...) {
    if (tag == NULL || gIsPause) {
        return;
    }
    if (gFilterLevel == LAGAN_LEVEL_OFF || level < gFilterLevel || tag == NULL || 
        strlen(tag) > LAGAN_MODULE_NAME_LEN_MAX - 1) {
        return;
    }

    char buf[LAGAN_RECORD_MAX_SIZE_DEFAULT] = {0};

    // 前缀
    LaganTime time = gGetTime();
    sprintf(buf, "%02d/%02d/%02d %02d:%02d:%02d.%06d %c/%s ", time.Year, time.Month, time.Day, time.Hour, time.Minute,
        time.Second, time.Us, gLevelCh[level], tag);
    gOutput((uint8_t*)buf, (int)strlen(buf));

    // 正文
    va_list args;
	va_start(args, format);

    int len = vsnprintf(buf, LAGAN_RECORD_MAX_SIZE_DEFAULT - 1, format, args);
    if (len > LAGAN_RECORD_MAX_SIZE_DEFAULT || len < 0) {
        len = LAGAN_RECORD_MAX_SIZE_DEFAULT;
    }
    gOutput((uint8_t*)buf, (int)strlen(buf));

    va_end(args);

    // 后缀
    gOutput((uint8_t*)"\n", 1);
}

// LaganPrintHex 打印字节流
void LaganPrintHex(char* tag, LaganLevel level, uint8_t* bytes, int size) {
    if (gIsPause) {
        return;
    }
    if (gFilterLevel == LAGAN_LEVEL_OFF || level < gFilterLevel) {
        return;
    }

    LaganPrint(tag, level, "");

    char buf[LAGAN_RECORD_MAX_SIZE_DEFAULT] = {0};

    char temp[16] = {0};
    int len = 0;
    for (int i = 0; i < size; i++) {
        if (len + 3 > LAGAN_RECORD_MAX_SIZE_DEFAULT - 1) {
            gOutput((uint8_t*)buf, len);
            buf[0] = '\0';
            len = 0;
        }

        if (i >= size - 1) {
            sprintf(temp, "%02x\n", bytes[i]);
        } else if (i != 0 && (i + 1) % 16 == 0) {
            sprintf(temp, "%02x\n", bytes[i]);
        } else {
            sprintf(temp, "%02x ", bytes[i]);
        }
        strcat(buf, temp);
        len += 3;
    }

    if (len > 0) {
        gOutput((uint8_t*)buf, len);
    }
}

// PaxPause 暂停日志打印
void LaganPause(void) {
    gIsPause = true;
}

// PaxResume 恢复日志打印
void LaganResume(void) {
    gIsPause = false;
}

// PaxIsPause 是否暂停
bool LaganIsPause(void) {
    return gIsPause;
}
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值