Home > Blockchain >  How to redirect stderr to a .txt file in C?
How to redirect stderr to a .txt file in C?

Time:09-26

I have a function that I use as a sort of way to print out some logging info to the terminal but I am trying to capture it to a log file as well. I am no C expert and am trying to gain some practice!

Here is what I tried

static void logging(const char *format, ...) {
    va_list args;
    //FILE *file_ptr;
    char log_file[] = "logs/TEST-LOG-001.txt";

    if (freopen(log_file, "w", stderr) == NULL) {
        printf("<---ERROR LOGGING TO FILES--->");
    }   
    else {
        fprintf(stderr, "LOG: ");
        va_start(args, format);
        vfprintf(stderr, format, args);
        va_end(args);
        fprintf(stderr, "\n");
        fclose(stderr);
    }   
}

What would be the proper way to redirect to a file. I was successful with something a bit more simpler where I am able to redirect stdout to a text file just using a hard coded array of strings and a hard coded amount of indexes I want to redirect to the text file similar to what is seen here.

On top of just redirecting stderr, how would I go about assigning a unique ID (like a timestamp) to the test-log file?

The overall purpose of my program is using some libav libs to decode videos into a series of images. What is returned to stdout is the overall information of the video file passed in (duration, format, resolution,etc) and each frame has corresponding info to it (frame number, size, type). I basically want to display the logging information to both stdout and to a log file.

Here is an example of what the data I am displaying looks like:

LOG: AVPacket->pts 0
LOG: AVPacket->pts 1024
LOG: AVPacket->pts 512
LOG: Frame 1 (type=I, size=100339 bytes, format=0) pts 0 key_frame 1 [DTS 0]
LOG: AVPacket->pts 256
LOG: Frame 2 (type=B, size=7484 bytes, format=0) pts 256 key_frame 0 [DTS 3]
LOG: AVPacket->pts 768

CodePudding user response:

Write the error log to stderr, normal log to stdout, redirect log messages to dedicated files accordingly by:

# write error message to `err.txt`, normal log to `info.txt`
./a.out 2>err.txt 1>info.txt

BTW: it's not recommend to rewrite existed *print* function. Use preprocessor macro such in case you wanna add more info such as tag:

#define LOG_ERR(fmt, ...)   fprintf(stderr, fmt, ##__VA_ARGS__)
#define LOG_INFO(fmt, ...)  fprintf(stdout, fmt, ##__VA_ARGS__)

// usage
LOG_ERR("[E] Something wrong!\n");
LOG_INFO("[I] Frame %d(type %c) ...\n", frame_number, frame_type);

CodePudding user response:

You can output the error messages to both stderr and a log file this way:

#include <stdarg.h>
#include <stdio.h>

static FILE *logfp;

// the log file should be opened at initialization time with
// logfp = fopen("logs/TEST-LOG-001.txt", "a");

static void logging(const char *format, ...) {
    va_list args, args2;

    va_start(args, format);
    if (logfp) {
        va_copy(args2, args);
        vfprintf(logfp, format, args2);
        // uncomment if the format strings do not include a newline
        //fprintf(logfp, "\n");
        va_end(args2);
    }
    fprintf(stderr, "LOG: ");
    vfprintf(stderr, format, args);
    // uncomment if the format strings do not include a newline
    //fprintf(stderr, "\n");
    va_end(args);
}
  •  Tags:  
  • c
  • Related