FOSSology  3.2.0rc1
Open Source License Compliance by Open Source Software
logging.c
Go to the documentation of this file.
1 /* **************************************************************
2 Copyright (C) 2010, 2011, 2012 Hewlett-Packard Development Company, L.P.
3 
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 version 2 as published by the Free Software Foundation.
7 
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12 
13 You should have received a copy of the GNU General Public License along
14 with this program; if not, write to the Free Software Foundation, Inc.,
15 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 ************************************************************** */
22 /* local includes */
23 #include <event.h>
24 #include <logging.h>
25 #include <scheduler.h>
26 
27 /* std library includes */
28 #define _GNU_SOURCE
29 #include <stdio.h>
30 #include <time.h>
31 
32 /* unix includes */
33 #include <sys/stat.h>
34 #include <sys/types.h>
35 #include <unistd.h>
36 
37 /* glib includes */
38 #include <glib.h>
39 
44 log_t* main_log = NULL;
45 
46 /* ************************************************************************** */
47 /* **** local functions ***************************************************** */
48 /* ************************************************************************** */
49 
54 typedef struct
55 {
57  gchar* msg;
59 
68 static void log_event(scheduler_t* scheduler, log_event_args* pass)
69 {
70  lprintf(pass->log, "%s", pass->msg);
71  g_free(pass->msg);
72  g_free(pass);
73 }
74 
75 /* ************************************************************************** */
76 /* **** logging functions *************************************************** */
77 /* ************************************************************************** */
78 
92 log_t* log_new(gchar* log_name, gchar* pro_name, pid_t pro_pid)
93 {
94  struct stat stats;
95  log_t* ret = g_new0(log_t, 1);
96 
97  /* set the process name */
98  if(pro_name == NULL)
99  ret->pro_name = g_strdup(SCHE_PRONAME);
100  else
101  ret->pro_name = g_strdup(pro_name);
102  ret->pro_pid = pro_pid;
103 
104  /* set the logs name */
105  if(strcmp(log_name, "stderr") != 0 && strcmp(log_name, "stdout") != 0 &&
106  (stat(log_name, &stats) == 0) && S_ISDIR(stats.st_mode))
107  ret->log_name = g_strdup_printf("%s/fossology.log", log_name);
108  else
109  ret->log_name = g_strdup(log_name);
110 
111  /* open the log file */
112  if (strcmp(ret->log_name, "stderr") == 0) { ret->log_file = stderr; }
113  else if(strcmp(ret->log_name, "stdout") == 0) { ret->log_file = stdout; }
114  else { ret->log_file = fopen(ret->log_name, "a"); }
115 
116  /* make sure that everything is valid */
117  if(ret->log_file == NULL)
118  {
119  ERROR("could not open log file \"%s\"", ret->log_name);
120  g_free(ret->pro_name);
121  g_free(ret->log_name);
122  return NULL;
123  }
124 
125  return ret;
126 }
127 
137 log_t* log_new_FILE(FILE* log_file, gchar* log_name, gchar* pro_name, pid_t pro_pid)
138 {
139  log_t* ret = g_new0(log_t, 1);
140 
141  if(pro_name == NULL)
142  ret->pro_name = g_strdup(SCHE_PRONAME);
143  else
144  ret->pro_name = g_strdup(pro_name);
145  ret->pro_pid = pro_pid;
146 
147  ret->log_name = g_strdup(log_name);
148  ret->log_file = log_file;
149 
150  V_JOB("NEW_LOG: log_name: \"%s\", pro_name: \"%s\", pro_pid: %d, log_file: %p\n",
151  ret->log_name, ret->pro_name, ret->pro_pid, ret->log_file);
152 
153  return ret;
154 }
155 
161 void log_destroy(log_t* log)
162 {
163  if(log->pro_name) g_free(log->pro_name);
164  if(log->log_name) g_free(log->log_name);
165 
166  if(log->log_file && log->log_file != stdout && log->log_file != stderr)
167  fclose(log->log_file);
168 
169  log->pro_name = NULL;
170  log->log_name = NULL;
171 
172  if(log->log_file != stdout && log->log_file != stderr)
173  log->log_file = NULL;
174 
175  g_free(log);
176 }
177 
191 int lprintf(log_t* log, const char* fmt, ...)
192 {
193  va_list args;
194  int rc;
195 
196  if(!fmt) return 0;
197 
198  va_start(args, fmt);
199  if(log == NULL || log->log_file == NULL)
200  {
201  rc = vlprintf(main_log, fmt, args);
202  }
203  else
204  {
205  rc = vlprintf(log, fmt, args);
206  }
207  va_end(args);
208 
209  return rc;
210 }
211 
224 int vlprintf(log_t* log, const char* fmt, va_list args)
225 {
226  /* static used to determine if a '\n' needs to be printed */
227  static int n_line = 1;
228 
229  /* locals */
230  time_t t = time(NULL);
231  char* tmp, * curr;
232  char time_buf[64];
233  int e_line;
234 
235  if(!fmt) return 0;
236  if(!log) return 0;
237 
238  strftime(time_buf, sizeof(time_buf),"%F %T",localtime(&t));
239 
240  tmp = g_strdup_vprintf(fmt, args);
241  e_line = tmp[strlen(tmp) - 1] == '\n';
242  curr = strtok(tmp, "\n");
243  while(curr != NULL)
244  {
245  if(n_line && fprintf(log->log_file, "%s %s [%d] :: ", time_buf,
246  log->pro_name, log->pro_pid) == 0)
247  return 0;
248 
249  if(fprintf(log->log_file, "%s", curr) == 0)
250  return 0;
251 
252  n_line = ((curr = strtok(NULL, "\n")) != NULL);
253  if(n_line && fprintf(log->log_file, "\n") == 0)
254  return 0;
255  }
256 
257  if(e_line)
258  {
259  n_line = 1;
260  if(fprintf(log->log_file, "\n") == 0)
261  return 0;
262  }
263 
264  fflush(log->log_file);
265  g_free(tmp);
266  return 1;
267 }
268 
281 int clprintf(log_t* log, char* s_name, uint16_t s_line, const char* fmt, ...)
282 {
283  va_list args;
284  int ret = 1;
285  log_event_args* pass;
286 
287  if(!fmt) return 0;
288  if(!log) return 0;
289 
290  va_start(args, fmt);
291  if(g_thread_self() != main_thread)
292  {
293  pass = g_new0(log_event_args, 1);
294  pass->log = log;
295  pass->msg = g_strdup_vprintf(fmt, args);
296  event_signal_ext(log_event, pass, "log_event", s_name, s_line);
297  }
298  else
299  {
300  ret = vlprintf(log, fmt, args);
301  }
302  va_end(args);
303 
304  return ret;
305 }
306 
307 
#define ERROR(...)
Definition: logging.h:90
log_t * log
Log to use.
Definition: logging.c:56
static void log_event(scheduler_t *scheduler, log_event_args *pass)
Definition: logging.c:68
void log_destroy(log_t *log)
Free memory associated with the log file.
Definition: logging.c:161
Definition: logging.h:45
FILE * log_file
The log file itself.
Definition: logging.h:50
int vlprintf(log_t *log, const char *fmt, va_list args)
The provides the same functionality for lprintf as vprintf does for printf.
Definition: logging.c:224
int clprintf(log_t *log, char *s_name, uint16_t s_line, const char *fmt,...)
Definition: logging.c:281
log_t * log_new_FILE(FILE *log_file, gchar *log_name, gchar *pro_name, pid_t pro_pid)
Creates a log file structure based on an already created FILE*.
Definition: logging.c:137
Log related operations.
gchar * pro_name
What should be printed as the process name.
Definition: logging.h:48
void event_signal_ext(void *func, void *args, char *name, char *s_name, uint16_t s_line)
Definition: event.c:206
uint16_t s_line
Sample source line number.
Definition: testEvent.c:39
log_t * log_new(gchar *log_name, gchar *pro_name, pid_t pro_pid)
Creates a new log.
Definition: logging.c:92
log_t * main_log
Definition: logging.c:44
int lprintf(log_t *log, const char *fmt,...)
Main logging function.
Definition: logging.c:191
gchar * log_name
The name of the log file that will be printed to.
Definition: logging.h:47
Event handling operations.
pid_t pro_pid
The pid of the process.
Definition: logging.h:49
gchar * msg
Message to log.
Definition: logging.c:57
GThread * main_thread
Pointer to the main thread.
Definition: scheduler.c:71
Header file for the scheduler.
char * s_name
Sample source file name.
Definition: testEvent.c:38