17

I am looking for a productive and simple logging library for C, which can output the log to a file. Displaying messages in the log I want to make like this:

date-time tag message

It would be nice to control the level of detail of messages and control the size of the file.

I found two projects that are suitable for me. It log4c and nglogc.

log4c seemed too big. nglogc quite fit, but also has a redundant functional. maybe you tell me more variants?

trafalgarx
  • 702
  • 2
  • 10
  • 13

6 Answers6

23

You can use this

File logger.h

#ifndef LOGGER_H
#define LOGGER_H

void logger(const char* tag, const char* message);

#endif /* LOG_H */

File logger.c

#include "logger.h"
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

void logger(const char* tag, const char* message) {
   time_t now;
   time(&now);
   printf("%s [%s]: %s\n", ctime(&now), tag, message);
}

It's probably not perfect, but it does satisfy the needs as you have presented them.

syb0rg
  • 8,057
  • 9
  • 41
  • 81
Edwin Buck
  • 69,361
  • 7
  • 100
  • 138
  • 2
    What about logging to a file? :) – pmg Jun 28 '11 at 17:19
  • I'm looking for the ability to output in the log file. I corrected the question that this be more understandable – trafalgarx Jun 29 '11 at 05:23
  • just use `fprintf` instead of `printf` above! – N.R.S.Sowrabh Jun 29 '11 at 05:30
  • 1
    For reliability's sake, it would also be desirable to flush the file stream after the message is printed. – jmbr Jun 29 '11 at 06:17
  • Flushing may or not be desirable. Turning it on will prevent problems where you want to read your log but it hasn't been written yet, but if you do a lot of logging it could also really start to impact the performance of your application. – Nate C-K Jan 25 '14 at 20:33
  • 4
    Without flushing what typically happens is that the log message you need the most didn't get written to disk. You'll lose a few messages if the application halts, and those messages are typically the most important ones (the cause of the crash). On the other hand, disks now have small ram caches, and write performance (while not great) is at least buffered. Now as for read/write locking, this is a file, and most file systems do not prevent inconsistent reads (however if logging to a database, that's a different story) – Edwin Buck Jan 26 '14 at 17:07
11

I suggest the log library which is written by myself --- zlog!

The way to fit your need in zlog is:

$ vi /etc/zlog.conf
[formats]
simple = "%D %c %m%n"
# don't know what the tag mean in your question, so put category of zlog instead
# log level is also available here, add %V means level

[rules]
my_cat.*   "xxx.log"; simple

$ vi hello.c
#include <stdio.h> 
#include "zlog.h"

int main(int argc, char** argv)
{
int rc;
zlog_category_t *c;

rc = dzlog_init("/etc/zlog.conf", "my_cat");
if (rc) {
    printf("init failed\n");
    return -1;
}

zlog_info(c, "hello, zlog");

zlog_fini();

return 0;
} 

It will generate xxx.log in current directory as

2012-09-30 07:22:50 my_cat hello, zlog

Links:

Download: https://github.com/HardySimpson/zlog/archive/latest-stable.tar.gz

UsersGuide: http://hardysimpson.github.com/zlog/UsersGuide-EN.html

Hompage: http://hardysimpson.github.com/zlog/

HardySimpson
  • 1,246
  • 1
  • 12
  • 14
  • Hello @HardySimpson, I got "init failed" return 255 when run hello.c. So, where is the log message file that I can find in the zlog_init, zc_debug(".... zlog_init start...."); – charles.cc.hsu Aug 16 '16 at 15:10
  • 1
    I've got to admit this is a bit silly and over-engineered. You've honestly just mostly re-created a non-standard syslog here. I was looking for something that you could specify as, say a argv switch and then optionally send to [syslog, file, stdout, stderr] .. with some portability to Windows. There really should never be a need for this much -- just send it to syslog! – A.B. Carroll Sep 25 '19 at 09:12
9
Here is mine:

log.h
------

#ifndef LOG_H 
#define LOG_H


void log_error(const char* message, ...); void log_info(const char* message, ...); void log_debug(const char* message, ...);

#endif

log.c
------
#include "log.h"


void log_format(const char* tag, const char* message, va_list args) {   time_t now;     time(&now);     char * date =ctime(&now);   date[strlen(date) - 1] = '\0';  printf("%s [%s] ", date, tag);  vprintf(message, args);     printf("\n"); }

void log_error(const char* message, ...) {  va_list args;   va_start(args, message);    log_format("error", message, args);     va_end(args); }

void log_info(const char* message, ...) {   va_list args;   va_start(args, message);    log_format("info", message, args);  va_end(args); }

void log_debug(const char* message, ...) {  va_list args;   va_start(args, message);    log_format("debug", message, args);     va_end(args); }

Have fun!

Babacar
  • 91
  • 1
  • 1
  • 1
    This is not necessarily a bad answer, but the question already had an accepted one from 2011. It isn't very constructive to answer questions this old unless you have information that would significantly benefit a reader. –  May 03 '14 at 15:18
5

You can use this simple logging library: https://github.com/kala13x/slog

Here is an example how to use:

At first you must init log. with init_log() function. First argument is log filename, second argument is log to file (1 enabled, 0 disabled) and third argument is max log level

init_slog("example", 1, 3);

print and log something

slog(0, "Test message with level 0");
slog(2, "Test message with level 2");
slog(0, "Test message with int argument: %d", int_arg);

Outout will be something like that:

2015:04:02:56 - Test message with level 0
2015:04:02:56 - Test message with level 2
2015:04:02:56 - Test message with int argument: 69

Sun Dro
  • 581
  • 4
  • 9
2

Take a look at the zf_log logging library. It's small, simple and provides essentials only. From README.md:

This is just a thin wrapper around sprintf() function. It provides less than 20% of functionality found in more sophisticated libraries, but covers more than 80% of common use cases. Focus is made on simplicity, ease of use and performance (to be more precise - low overhead).

Features:

  • Debug logging is reduced to no-op in release builds
  • Arguments are not evaluated when the message is not logged
  • No "unused" warning for variables used in log statements only
  • Log a memory region as HEX and ASCII
  • Custom output functions
wonder.mice
  • 7,227
  • 3
  • 36
  • 39
0

I am also finding solutions on this problem. The answer from @edwin-buck is just simple and OK for my need.

I really know nothing on multi-threading and thread-safe, but after compiling under Visual Studio compiler (it can give some warnings and tips), and searching through google, I think a few modification might make the code above thread-safe and better.

// file log.c
void log(const char* tag, const char* message) {
   time_t now;
   struct tm _calendar_time;
   char _buf[MAX_COUNT];

   time(&now);
   localtime_s(&_calendar_time, &now);

   strftime(_buf, MAX_COUNT, "%c", &_calendar_time);
   printf("%s [%s]: %s\n", _buf, tag, message);
}

Feel free to correct me if wrong.

jtuki
  • 385
  • 1
  • 5
  • 8