调用静态记录器的格式化日志方法

时间:2017-03-28 13:51:38

标签: c++ logging

我的项目中有一些代码,但我找不到为什么我在日志文件中找不到format参数。当我像这样调用我的记录器时:

logger::get_logger().repare().log("log something");

但是,日志文件仍然打开,log()方法中的内容“log:”显示在日志文件中,表明代码有效。像这样 : 预期:

======== new log =======
repare.log : Time : 19:05:17. log something

但是得到:

======== new log =======
repare.log :

我认为使用vsprintf的代码是正确的,这是从教程中复制的。

这是我的代码。

 class Logger : private noncopyable {
        public :
            Logger();
            ~Logger();
            static Logger& get_logger();
            Logger& repare();
            int log(const char* format, ...);
        private :
            string filename_;
            int fd_;
    };

int my_http::DeployLogFile() {
    char filename[100];
    int fd;
    sprintf(filename, "%s/stuff/log.txt", GET_MY_ROOT_PATH);
    fd = open(filename, O_WRONLY | O_TRUNC | O_APPEND);
    if (fd == -1) {
        fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_APPEND, S_IRUSR | S_IWUSR | S_IROTH);
    } else {
        cout << "log exist!!!" << endl;
    }
    exit_if(fd<0, "error in open log file");
    char buff[100];
    sprintf(buff, "======== new log =======\n");
    write(fd, buff, strlen(buff));
    return fd;
}

Logger::Logger() {
    fd_ = -1;
}

Logger::~Logger() {
    if (fd_ != -1) {
        close(fd_);
    }
}

Logger& Logger::get_logger() {
    static Logger lg;
    return lg;
}

Logger& Logger::repare() {
    int fd = DeployLogFile();
    if (fd == -1) {
        perror("deploy log fail");
    } else {
        fd_ = fd;
    }
    char buff[100];
    sprintf(buff, "repare.");
    write(fd, buff, strlen(buff));
    return *this;
}

int Logger::log(const char* format, ...) {
    va_list arglist;
    va_start(arglist, format);

    char buf[100];
    sprintf(buf, "log : ");
    write(fd_, buf, strlen(buf));

    char buff[500];
    sprintf(buff, "Time : %s. ", __TIME__);
    vsprintf(buff, format, arglist);
    sprintf(buff, "\n");

    write(fd_, buff, strlen(buff));
    va_end(arglist);
    return strlen(buff);
}

1 个答案:

答案 0 :(得分:0)

嗯,这是因为你用“\ n”覆盖了buff,当然在新行后{0}检查strlen后包含0,只将新行'0'写入文件。你可能的意思是:

buff

输出

#include <string.h>
#include <iostream>
#include <stdarg.h>
#include <fcntl.h>
#include <cstdio>
#include <cstdlib>
#include <unistd.h>

using namespace std;

class Logger {
        public :
            Logger();
            ~Logger();
            static Logger& get_logger();
            Logger& repare();
            int log(const char* format, ...);
        private :
            string filename_;
            int fd_;
};

int DeployLogFile() {
    char filename[100];
    int fd;
    sprintf(filename, "%s/log.txt", "/tmp");
    fd = open(filename, O_WRONLY | O_TRUNC | O_APPEND);
    if (fd == -1) {
        fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_APPEND, S_IRUSR | S_IWUSR | S_IROTH);
    } else {
        cout << "log exist!!!" << endl;
    }
    if (fd<0) 
    { 
    write(1, "error in open log file", strlen("error in open log file"));
    exit(-1);
    }
    char buff[100];
    sprintf(buff, "======== new log =======\n");
    write(fd, buff, strlen(buff));
    return fd;
}

Logger::Logger() {
    fd_ = -1;
}

Logger::~Logger() {
    if (fd_ != -1) {
        close(fd_);
    }
}

Logger& Logger::get_logger() {
    static Logger lg;
    return lg;
}

Logger& Logger::repare() {
    int fd = DeployLogFile();
    if (fd == -1) {
        perror("deploy log fail");
    } else {
        fd_ = fd;
    }
    char buff[100];
    sprintf(buff, "repare.");
    write(fd, buff, strlen(buff));
    return *this;
}

int Logger::log(const char* format, ...) {
    va_list arglist;
    va_start(arglist, format);

    char buf[100];
    sprintf(buf, "log : ");
    write(fd_, buf, strlen(buf));

    char buff[500];
    sprintf(buff, "Time : %s. ", __TIME__);
    int offset = strlen(buff) ;
    vsprintf(buff + offset, format, arglist);
    sprintf(buff + strlen(buff), "\n");
    write(fd_, buff, strlen(buff));
    va_end(arglist);
    return strlen(buff);
}

int main(void){

    Logger::get_logger().repare().log("%s", "log something");
    return 0;
}

然后 - 可能这不是你真正想要的东西 - 因为你想写:

======== new log =======
repare.log : Time : 19:05:17. log something

会离开你

Logger::get_logger().repare().log("%s", "log something");
Logger::get_logger().repare().log("%s %d %s", "crazy whatamai", 42, "log even more");