Skip to content

Instantly share code, notes, and snippets.

@neeraj9
Created March 29, 2018 12:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save neeraj9/34bf16736cc3c0394274c7628c7683c8 to your computer and use it in GitHub Desktop.
Save neeraj9/34bf16736cc3c0394274c7628c7683c8 to your computer and use it in GitHub Desktop.
Demonstrate Application Logging in C Programming Language
/*
* Copyright (c) 2015 Neeraj Sharma. All rights reserved.
*
* Licensed under GNU GPL v3 License.
* License: https://www.gnu.org/licenses/gpl-3.0.txt
*
* Code style based on the Linux Kernel, see
* https://www.kernel.org/doc/Documentation/CodingStyle
* for more details.
*
* indent with the following options
* -kr -i8 -ts8 -sob -l80 -ss -bs -psl
*/
#include <stdio.h> /* fprintf() and friends */
#include <string.h> /* strncpy() */
#include <sys/time.h> /* gmtime_r() */
#include <sys/types.h>
#include <time.h> /* time() */
#include <unistd.h> /* getpid(), gethostname() */
#define MAX_PROG_NAME_LEN 40
#define MAX_HOSTNAME_LEN 20
static char g_progname[MAX_PROG_NAME_LEN] = {0};
static char g_hostname[MAX_HOSTNAME_LEN] = {0};
static int g_pid = 0;
#define LOG_ERROR(msg) logmsg(__func__, __LINE__, "ERROR", (msg))
/*
* Get the current time in c string with '\0' termination
* and returns the length of the string.
* The current implementation follows the ISO 8601 date and time
* combined format with a resolution of seconds in the UTC timezone.
* In case of error -1 is retured.
*/
int
time_to_cstr(time_t *t, char *timestr, int maxlen)
{
struct tm tms;
gmtime_r(t, &tms);
snprintf(timestr, maxlen, "%04d-%02d-%02dT%02d:%02d:%02d+00:00",
tms.tm_year + 1900, tms.tm_mon + 1, tms.tm_mday,
tms.tm_hour, tms.tm_min, tms.tm_sec);
}
void
logmsg(const char *funcname, int linenum, const char *level, const char *msg)
{
/* ISO 8601 date and time format with sec */
const int time_str_len = 26;
char time_str[time_str_len];
time_t now;
int len = 0;
int ret = 0;
time(&now);
len = time_to_cstr(&now, time_str, time_str_len);
if (len < 0) {
/* huh! I'd like to crash at this point but
* lets just log the message, which is a must.
*/
return;
}
/* <HEADER> <MESSAGE>
* <HEADER> = <TIMESTAMP> <HOSTNAME>
* <MESSAGE> = <TAG> <LEVEL> <CONTENT>
* <TAG> = <PROGRAM>[<PID>]
* <LEVEL> = DEBUG | INFO | WARNING | ERROR
* <CONTENT> = <FUNCTION/MODULE>: <APPLICATION_MESSAGE>
*/
fprintf(stderr, "%s %s %s[%d] %s %s(%d): %s\n", time_str, g_hostname,
g_progname, g_pid, level, funcname, linenum, msg);
}
void display_welcome(void)
{
logmsg(__func__, __LINE__, "ERROR", "a log entry");
LOG_ERROR("Another log message");
}
int
main(int argc, char *argv[])
{
int ret = 0;
strncpy(g_progname, argv[0], MAX_PROG_NAME_LEN);
ret = gethostname(g_hostname, MAX_HOSTNAME_LEN);
if (ret < 0) {
strncpy(g_hostname, "unknown", MAX_HOSTNAME_LEN);
}
g_pid = (int)getpid();
display_welcome();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment