如何实现FIFO日志文件?

时间:2015-10-18 14:36:32

标签: c linux logging fifo circular-buffer

如果网络连接丢失,我试图使用FIFO文件为我的应用程序存储缓冲的日志条目。我想当从FIFO文件中读取时,它将被完全删除,因此它将被弹出"来自日志队列。

但是,我的方法一直在无限期地记录相同的文本。也许将所有条目读入缓冲区并尝试将它们记录到数据库并写回所有无法记录的条目会更容易。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>

/**
 * First argument is the filename
 * Second argument is the log message
 * Third argument is the severity
 */
int main(int argc, char **argv) {
  int err, severity;
  char c;
  char *fifoName = "/tmp/bufferedlog";
  char src[100], msg[100];
  FILE *fp;

  /**
   * if the program has exactly three arguments it will push
   * a new log entry to the queue.
   */
  if(argc == 3) {
    fp = fopen(fifoName, "w");
    if(fp == NULL) {
      err = mknod(fifoName, S_IFIFO | 0600, 0);
      if(err < 0){
        fprintf(stderr, "Unable to create fifo: %s\n",fifoName);
        exit(EXIT_FAILURE);
      }
      fp = fopen(fifoName, "w");
      if(fp == NULL) {
        fprintf(stderr, "Unable to open fifo for writing\n");
        exit(EXIT_FAILURE);
      }
    }
    fprintf(fp, "\"%s\" \"%s\" %d ","My Application", argv[1], atoi(argv[2]));
    fflush(fp);
    fclose(fp);
    return 0;
  }

  fp = fopen(fifoName, "r");
  if(fp == NULL) {
    fprintf(stderr, "Unable to open fifo for reading\n");
    exit(EXIT_FAILURE);
  }

  /**
   * it will now try to read the log entry from the fifo file.
   */
  while(1) {
    if(fscanf(fp,"\"%[^\"]\" \"%[^\"]\" %d", src, msg, &severity) < 0) { // ignore the overflow bugs
      goto finish;
    }

    fprintf(stdout, "Do you really want to log \"%s (%d):%s\" to database [y/n]?\n", src, severity, msg);
    scanf(" %c",&c);
    if(c=='y') {
      /* logs to database here */
      /* if it fails to log to database it will break out of this loop */
      fprintf(stdout, "Pushed log entry to database.\n");
    }else {
      goto finish;
    }
  }         
  fclose(fp);
  fp = fopen(fifoName, "w");

  /**
   * if the database connection failed it fill put the log entry back into
   * the queue and try again when the program starts next time.
   */
  if(fp == NULL) {
    fprintf(stderr, "Unable to open fifo for writing\n");
    exit(EXIT_FAILURE);
  }
  fprintf(fp, "\"%s\" \"%s\" %d ", src, msg, severity);
  fflush(fp);
  finish:
  fclose(fp);
  return 0;
}

请忽略scanf的溢出错误。我的尝试不起作用,这是我程序的伪代码。

if argc is equal to three then
  write log entry to fifo file
end
while there is data in fifo file do
  read log entry from fifo file and delete it from fifo file
  try logging entry to database
  if failed then
    break out of while loop
  end
end
write log entry back to fifo file

0 个答案:

没有答案