简单的Log实现

#ifndef __MESWEBLOG_H_
#define __MESWEBLOG_H_
#include <stdarg.h>
#include <stdio.h>
#define MES_INLINE inline
#define _MES_BEGIN_DECLS 
#define _MES_END_DECLS 
#define MES_FORMAT(x, y)
_MES_BEGIN_DECLS
typedef enum {
    MES_LOGLEVEL_TRACE,
    MES_LOGLEVEL_DEBUG,
    MES_LOGLEVEL_INFO,
    MES_LOGLEVEL_WARNING,
    MES_LOGLEVEL_ERROR,
    MES_LOGLEVEL_FATAL
} MES_LogLevel;

typedef enum {
    MES_LOGCATEGORY_NETWORK,
    MES_LOGCATEGORY_SECURECHANNEL,
    MES_LOGCATEGORY_SESSION,
    MES_LOGCATEGORY_SERVER,
    MES_LOGCATEGORY_CLIENT,
    MES_LOGCATEGORY_USERLAND,
    MES_LOGCATEGORY_SECURITYPOLICY
} MES_LogCategory;

struct mytm {
    int tm_sec;
    int tm_min;
    int tm_hour;
    int tm_mday;
    int tm_mon;
    int tm_year;
};

typedef struct {
    /* Log a message. The message string and following varargs are formatted
     * according to the rules of the printf command. Use the convenience macros
     * below that take the minimum log-level defined in ua_config.h into
     * account. */
    void (*log)(void* logContext, MES_LogLevel level, MES_LogCategory category,
        const char* msg, va_list args);

    void* context; /* Logger state */

    void (*clear)(void* context); /* Clean up the logger plugin */
} MES_Logger;

static MES_INLINE MES_FORMAT(3, 4) void
MES_LOG_TRACE(const MES_Logger* logger, MES_LogCategory category, const char* msg, ...) {
#if MES_LOGLEVEL <= 100
    if (!logger || !logger->log)
        return;
    va_list args; va_start(args, msg);
    logger->log(logger->context, MES_LOGLEVEL_TRACE, category, msg, args);
    va_end(args);
#else
    (void)logger;
    (void)category;
    (void)msg;
#endif
}

static MES_INLINE MES_FORMAT(3, 4) void
MES_LOG_DEBUG(const MES_Logger* logger, MES_LogCategory category, const char* msg, ...) {
#if UA_LOGLEVEL <= 200
    if (!logger || !logger->log)
        return;
    va_list args; va_start(args, msg);
    logger->log(logger->context, MES_LOGLEVEL_DEBUG, category, msg, args);
    va_end(args);
#else
    (void)logger;
    (void)category;
    (void)msg;
#endif
}

static MES_INLINE MES_FORMAT(3, 4) void
MES_LOG_INFO(const MES_Logger* logger, MES_LogCategory category, const char* msg, ...) {
#if UA_LOGLEVEL <= 300
    if (!logger || !logger->log)
        return;
    va_list args; va_start(args, msg);
    logger->log(logger->context, MES_LOGLEVEL_INFO, category, msg, args);
    va_end(args);
#else
    (void)logger;
    (void)category;
    (void)msg;
#endif
}

static MES_INLINE MES_FORMAT(3, 4) void
MES_LOG_WARNING(const MES_Logger* logger, MES_LogCategory category, const char* msg, ...) {
#if MES_LOGLEVEL <= 400
    if (!logger || !logger->log)
        return;
    va_list args; va_start(args, msg);
    logger->log(logger->context, MES_LOGLEVEL_WARNING, category, msg, args);
    va_end(args);
#else
    (void)logger;
    (void)category;
    (void)msg;
#endif
}

static MES_INLINE MES_FORMAT(3, 4) void
MES_LOG_ERROR(const MES_Logger* logger, MES_LogCategory category, const char* msg, ...) {
#if MES_LOGLEVEL <= 500
    if (!logger || !logger->log)
        return;
    va_list args; va_start(args, msg);
    logger->log(logger->context, MES_LOGLEVEL_ERROR, category, msg, args);
    va_end(args);
#else
    (void)logger;
    (void)category;
    (void)msg;
#endif
}

static MES_INLINE MES_FORMAT(3, 4) void
MES_LOG_FATAL(const MES_Logger* logger, MES_LogCategory category, const char* msg, ...) {
#if MES_LOGLEVEL <= 600
    if (!logger || !logger->log)
        return;
    va_list args; va_start(args, msg);
    logger->log(logger->context, MES_LOGLEVEL_FATAL, category, msg, args);
    va_end(args);
#else
    (void)logger;
    (void)category;
    (void)msg;
#endif
}
_MES_END_DECLS



#include<limits.h>
/* 2000-03-01 (mod 400 year, immediately after feb29 */
#define LEAPOCH (946684800LL + 86400*(31+29))
#define DAYS_PER_400Y (365*400 + 97)
#define DAYS_PER_100Y (365*100 + 24)
#define DAYS_PER_4Y   (365*4   + 1)

int __secs_to_tm(long long t, struct mytm* tm) {
    long long days, secs, years;
    int remdays, remsecs, remyears;
    int qc_cycles, c_cycles, q_cycles;
    int months;
    static const char days_in_month[] = { 31,30,31,30,31,31,30,31,30,31,31,29 };

    /* Reject time_t values whose year would overflow int */
    if (t < INT_MIN * 31622400LL || t > INT_MAX * 31622400LL)
        return -1;

    secs = t - LEAPOCH;
    days = secs / 86400LL;
    remsecs = (int)(secs % 86400);
    if (remsecs < 0) {
        remsecs += 86400;
        --days;
    }

    qc_cycles = (int)(days / DAYS_PER_400Y);
    remdays = (int)(days % DAYS_PER_400Y);
    if (remdays < 0) {
        remdays += DAYS_PER_400Y;
        --qc_cycles;
    }

    c_cycles = remdays / DAYS_PER_100Y;
    if (c_cycles == 4) --c_cycles;
    remdays -= c_cycles * DAYS_PER_100Y;

    q_cycles = remdays / DAYS_PER_4Y;
    if (q_cycles == 25) --q_cycles;
    remdays -= q_cycles * DAYS_PER_4Y;

    remyears = remdays / 365;
    if (remyears == 4) --remyears;
    remdays -= remyears * 365;

    years = remyears + 4 * q_cycles + 100 * c_cycles + 400LL * qc_cycles;

    for (months = 0; days_in_month[months] <= remdays; ++months)
        remdays -= days_in_month[months];

    if (years + 100 > INT_MAX || years + 100 < INT_MIN)
        return -1;

    tm->tm_year = (int)(years + 100);
    tm->tm_mon = months + 2;
    if (tm->tm_mon >= 12) {
        tm->tm_mon -= 12;
        ++tm->tm_year;
    }
    tm->tm_mday = remdays + 1;
    tm->tm_hour = remsecs / 3600;
    tm->tm_min = remsecs / 60 % 60;
    tm->tm_sec = remsecs % 60;

    return 0;
}

#include <windows.h>
//#include <minwindef.h>
#include <time.h>
#include<string>
#include<iostream>
#include<fstream>
typedef unsigned __int16  uint16_t;
typedef uint16_t MES_UInt16;
typedef signed __int64 int64_t;
typedef int64_t MES_DateTime;
typedef int64_t MES_Int64;
#define ANSI_COLOR_RESET ""
#define MES_DATETIME_USEC 10LL
#define MES_MAXTIMEOUT    50
#define MES_DATETIME_MSEC (MES_DATETIME_USEC * 1000LL)
#define MES_DATETIME_SEC  (MES_DATETIME_MSEC * 1000LL)
#define MES_DATETIME_UNIX_EPOCH (11644473600LL * MES_DATETIME_SEC)
#ifdef UA_ENABLE_LOG_COLORS
    # define ANSI_COLOR_RED     "\x1b[31m"
    # define ANSI_COLOR_GREEN   "\x1b[32m"
    # define ANSI_COLOR_YELLOW  "\x1b[33m"
    # define ANSI_COLOR_BLUE    "\x1b[34m"
    # define ANSI_COLOR_MAGENTA "\x1b[35m"
    # define ANSI_COLOR_CYAN    "\x1b[36m"
    # define ANSI_COLOR_RESET   "\x1b[0m"
#else
    # define ANSI_COLOR_RED     ""
    # define ANSI_COLOR_GREEN   ""
    # define ANSI_COLOR_YELLOW  ""
    # define ANSI_COLOR_BLUE    ""
    # define ANSI_COLOR_MAGENTA ""
    # define ANSI_COLOR_CYAN    ""
    # define ANSI_COLOR_RESET   ""
#endif

typedef struct MES_DateTimeStruct {
    MES_UInt16 nanoSec;
    MES_UInt16 microSec;
    MES_UInt16 milliSec;
    MES_UInt16 sec;
    MES_UInt16 min;
    MES_UInt16 hour;
    MES_UInt16 day;   /* From 1 to 31 */
    MES_UInt16 month; /* From 1 to 12 */
    MES_UInt16 year;
} MES_DateTimeStruct;

const char* logLevelNames[6] = { "trace", "debug",
                                ANSI_COLOR_GREEN "info",
                                ANSI_COLOR_YELLOW "warn",
                                ANSI_COLOR_RED "error",
                                ANSI_COLOR_MAGENTA "fatal" };
const char* logCategoryNames[7] = { "network", "channel", "session", "server",
                                   "client", "userland", "securitypolicy" };

const char* logMesFunction[] = {"DeviceStatus", "Alarm", "Product",
                                "Process", "Orders", "PersonCheck",
                                "MaterialCheck", "DeviceStartUpCheck"};

MES_DateTime MES_DateTime_now(void) 
{
    /* Windows filetime has the same definition as UA_DateTime */
    FILETIME ft;
    SYSTEMTIME st;
    GetSystemTime(&st);
    SystemTimeToFileTime(&st, &ft);
    ULARGE_INTEGER ul;
    ul.LowPart = ft.dwLowDateTime;
    ul.HighPart = ft.dwHighDateTime;
    return (MES_DateTime)ul.QuadPart;
}

MES_Int64 MES_DateTime_localTimeUtcOffset(void) {
    time_t gmt, rawtime = time(NULL);
    struct tm ptm;
    gmtime_s(&ptm, &rawtime);
    // Request that mktime() looksup dst in timezone database
    ptm.tm_isdst = -1;
    gmt = mktime(&ptm);

    return (MES_Int64)(difftime(rawtime, gmt) * MES_DATETIME_SEC);
}

MES_DateTimeStruct MES_DateTime_toStruct(MES_DateTime t)
{
    /* Calculating the the milli-, micro- and nanoseconds */
    MES_DateTimeStruct dateTimeStruct;
    if (t >= 0) {
        dateTimeStruct.nanoSec = (MES_UInt16)((t % 10) * 100);
        dateTimeStruct.microSec = (MES_UInt16)((t % 10000) / 10);
        dateTimeStruct.milliSec = (MES_UInt16)((t % 10000000) / 10000);
    }
    else {
        dateTimeStruct.nanoSec = (MES_UInt16)(((t % 10 + t) % 10) * 100);
        dateTimeStruct.microSec = (MES_UInt16)(((t % 10000 + t) % 10000) / 10);
        dateTimeStruct.milliSec = (MES_UInt16)(((t % 10000000 + t) % 10000000) / 10000);
    }

    /* Calculating the unix time with #include <time.h> */
    long long secSinceUnixEpoch = (long long)(t / MES_DATETIME_SEC)
        - (long long)(MES_DATETIME_UNIX_EPOCH / MES_DATETIME_SEC);
    struct mytm ts;
    memset(&ts, 0, sizeof(struct mytm));
    __secs_to_tm(secSinceUnixEpoch, &ts);
    dateTimeStruct.sec   = (MES_UInt16)ts.tm_sec;
    dateTimeStruct.min   = (MES_UInt16)ts.tm_min;
    dateTimeStruct.hour  = (MES_UInt16)ts.tm_hour;
    dateTimeStruct.day   = (MES_UInt16)ts.tm_mday;
    dateTimeStruct.month = (MES_UInt16)(ts.tm_mon + 1);
    dateTimeStruct.year  = (MES_UInt16)(ts.tm_year + 1900);
    return dateTimeStruct;
}

void UA_Log_Print(MES_Int64 tOffset, MES_DateTimeStruct dts, MES_LogLevel level, MES_LogCategory category, std::string szLogMess)
{
    char szLogMsg[512] = { 0 };
    char szLogFileName[64] = { 0 };
    sprintf(szLogMsg, "[%04u-%02u-%02u %02u:%02u:%02u.%03u (UTC%+05d)] %s/%s" ANSI_COLOR_RESET "\t", dts.year, dts.month, dts.day, dts.hour, dts.min, dts.sec, dts.milliSec,
        (int)(tOffset / MES_DATETIME_SEC / 36), logLevelNames[level], logCategoryNames[category]);
    sprintf(szLogFileName, "%04u%02u%uKingViewMes.log", dts.year, dts.month, dts.day);
    std::string szLogTime(szLogMsg);
    std::string strLogFileName(szLogFileName);
    std::fstream m_FsFile;
    m_FsFile.open(strLogFileName, std::ios::app | std::ios::out | std::ios::in);
    m_FsFile << szLogTime << szLogMess << std::endl;
    m_FsFile.close();
}

inline void MES_Log_Stdout_log(void* context, MES_LogLevel level, MES_LogCategory category,
    const char* msg, va_list args) {

    /* Assume that context is casted to UA_LogLevel */
    /* TODO we may later change this to a struct with bitfields to filter on category */
    if (context != NULL && (MES_LogLevel)(uintptr_t)context > level)
        return;

    MES_Int64 tOffset = MES_DateTime_localTimeUtcOffset();
    MES_DateTimeStruct dts = MES_DateTime_toStruct(MES_DateTime_now() + tOffset);

#if MES_MULTITHREADING >= 200
    pthread_mutex_lock(&printf_mutex);
#endif

    printf("[%04u-%02u-%02u %02u:%02u:%02u.%03u (UTC%+05d)] %s/%s" ANSI_COLOR_RESET "\t",
        dts.year, dts.month, dts.day, dts.hour, dts.min, dts.sec, dts.milliSec,
        (int)(tOffset / MES_DATETIME_SEC / 36), logLevelNames[level], logCategoryNames[category]);
    vprintf(msg, args);
    char szLogMsg[512] = { 0 };
    vsprintf(szLogMsg, msg, args);
#ifdef  UA_ENABLE_MES
    UA_Log_Print(tOffset, dts, level, category, szLogMsg);
#endif
    printf("\n");
    fflush(stdout);

#if UA_MULTITHREADING >= 200
    pthread_mutex_unlock(&printf_mutex);
#endif
}

inline void MES_Log_Stdout_clear(void* logContext)
{

}

const MES_Logger  MES_Log_Stdout_ = { MES_Log_Stdout_log, NULL, MES_Log_Stdout_clear };
const MES_Logger* MES_Log_Stdout  = &MES_Log_Stdout_;

/* By default the client and server is configured with UA_Log_Stdout
   This constructs a logger with a configurable max log level */

MES_Logger UA_Log_Stdout_withLevel(MES_LogLevel minlevel)
{
    MES_Logger logger = { MES_Log_Stdout_log, (void*)minlevel, MES_Log_Stdout_clear };
    return logger;
}
#endif
/* MES_Int64 tOffset = MES_DateTime_localTimeUtcOffset();
   MES_DateTimeStruct dts = MES_DateTime_toStruct(MES_DateTime_now() + tOffset);
   MES_LOG_INFO(MES_Log_Stdout, MES_LOGCATEGORY_USERLAND, "date is: %u-%u-%u %u:%u:%u.%03u\n",
        dts.day, dts.month, dts.year, dts.hour, dts.min, dts.sec, dts.milliSec);*/
MES_LOG_INFO(MES_Log_Stdout, MES_LOGCATEGORY_NETWORK, "Reconnect to server is %d | The response is %s.", nRet, szResponse.c_str());

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值