CUBRID Engine  latest
shard_proxy_log.c
Go to the documentation of this file.
1 /*
2  * Copyright 2008 Search Solution Corporation
3  * Copyright 2016 CUBRID Corporation
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */
18 
19 
20 /*
21  * shard_proxy_log.c -
22  */
23 
24 #ident "$Id$"
25 
26 #include <assert.h>
27 
28 #include "shard_proxy_log.h"
29 #include "broker_util.h"
30 #include "cas_util.h"
31 
32 #define PROXY_LOG_BUFFER_SIZE (8192)
33 
34 static char *make_proxy_log_filename (char *filepath_buf, size_t buf_size, const char *br_name, int proxy_index);
35 static void proxy_log_backup (void);
36 static void proxy_log_write_internal (int level, char *svc_code, bool do_flush, const char *fmt, va_list ap);
37 static void proxy_log_reset (void);
38 
39 static FILE *log_open (char *log_file_name);
40 
41 #ifdef CAS_ERROR_LOG
42 static int error_file_offset;
43 static char cas_log_error_flag;
44 #endif
45 static FILE *log_fp = NULL;
46 static FILE *access_log_fp = NULL;
48 
49 extern int proxy_id;
51 extern T_SHM_PROXY *shm_proxy_p;
53 
54 static const char *proxy_log_level_str[] = {
55  "NUL",
56  "ERR",
57  "TMO",
58  "NTC",
59  "SRD",
60  "SCH",
61  "DBG"
62 };
63 
64 static char *
65 make_proxy_log_filename (char *filepath_buf, size_t buf_size, const char *br_name, int proxy_index)
66 {
68 
69  assert (filepath_buf != NULL);
70 
71  strcpy (dirname, shm_as_p->proxy_log_dir);
72 
73  if (snprintf (filepath_buf, buf_size, "%s/%s_%d.log", dirname, br_name, proxy_index + 1) < 0)
74  {
75  filepath_buf[0] = '\0';
76  }
77  return filepath_buf;
78 }
79 
80 void
81 proxy_log_open (char *br_name, int proxy_index)
82 {
83  if (log_fp != NULL)
84  {
85  proxy_log_close ();
86  }
87 
88  if (proxy_info_p->cur_proxy_log_mode != PROXY_LOG_MODE_NONE)
89  {
90  if (br_name != NULL)
91  {
93  }
94 
95  /* note: in "a+" mode, output is always appended */
96  log_fp = fopen (log_filepath, "r+");
97  if (log_fp != NULL)
98  {
99  fseek (log_fp, 0, SEEK_END);
100  }
101  else
102  {
103  log_fp = fopen (log_filepath, "w");
104  }
105  }
106  else
107  {
108  log_fp = NULL;
109  }
110 
111  proxy_info_p->proxy_log_reset = 0;
112 }
113 
114 static void
116 {
117  if (proxy_info_p->proxy_log_reset)
118  {
119  if (log_fp != NULL)
120  {
121  proxy_log_close ();
122  }
123 
124  proxy_log_open (shm_as_p->broker_name, proxy_id);
125  }
126 }
127 
128 void
130 {
131  if (log_fp != NULL)
132  {
133  fclose (log_fp);
134  log_fp = NULL;
135  }
136 }
137 
138 static void
140 {
141  char backup_filepath[BROKER_PATH_MAX];
142 
143  assert (log_filepath[0] != '\0');
144 
145  if (snprintf (backup_filepath, BROKER_PATH_MAX - 1, "%s.bak", log_filepath) < 0)
146  {
147  abort ();
148  }
149 
150  unlink (backup_filepath);
151  rename (log_filepath, backup_filepath);
152 }
153 
154 void
156 {
157  long log_fpos;
158  long log_size_max;
159 
160  log_size_max = shm_as_p->proxy_log_max_size;
161 
162  log_fpos = ftell (log_fp);
163  if ((log_fpos / 1000) > log_size_max)
164  {
165  proxy_log_close ();
166  proxy_log_backup ();
167  proxy_log_open (shm_as_p->broker_name, proxy_id);
168  }
169 
170  return;
171 }
172 
173 static void
174 proxy_log_write_internal (int level, char *svc_code, bool do_flush, const char *fmt, va_list ap)
175 {
176  char buf[PROXY_LOG_BUFFER_SIZE], *p;
177  int write_len, remain, n;
178 
179  p = buf;
180  remain = PROXY_LOG_BUFFER_SIZE;
181 
182  n = ut_time_string (p, NULL);
183  remain -= n;
184  p += n;
185 
186  if (remain > 0)
187  {
188  if (svc_code == NULL)
189  {
190  n = snprintf (p, remain, " [%s] ", proxy_log_level_str[level]);
191  }
192  else
193  {
194  n = snprintf (p, remain, " [%s][%s] ", proxy_log_level_str[level], svc_code);
195  }
196 
197  if (n < 0)
198  {
199  n = 0;
200  }
201  else if (n >= remain)
202  {
203  n = (remain - 1);
204  }
205 
206  remain -= n;
207  p += n;
208 
209  if (remain > 0)
210  {
211  n = vsnprintf (p, remain, fmt, ap);
212  if (n < 0)
213  {
214  n = 0;
215  }
216  else if (n >= remain)
217  {
218  n = (remain - 1);
219  }
220 
221  remain -= n;
222  p += n;
223  }
224  }
225 
226  write_len = MIN ((int) (p - buf), PROXY_LOG_BUFFER_SIZE);
227  fwrite (buf, write_len, 1, log_fp);
228  fputc ('\n', log_fp);
229 
230  if (do_flush == true)
231  {
232  fflush (log_fp);
233  }
234 }
235 
236 void
237 proxy_log_write (int level, char *svc_code, const char *fmt, ...)
238 {
239  if (log_fp == NULL)
240  {
241  proxy_log_open (shm_as_p->broker_name, proxy_id);
242  }
243 
244  if (level <= PROXY_LOG_MODE_NONE || level > PROXY_LOG_MODE_ALL)
245  {
246  return;
247  }
248 
249  if (level > proxy_info_p->cur_proxy_log_mode)
250  {
251  return;
252  }
253 
254  proxy_log_reset ();
255 
256  if (log_fp != NULL)
257  {
258  va_list ap;
259 
260  va_start (ap, fmt);
261  proxy_log_write_internal (level, svc_code, true, fmt, ap);
262  va_end (ap);
263 
264  proxy_log_end ();
265  }
266 }
267 
268 int
270 {
271  return proxy_info_p->cur_proxy_log_mode;
272 }
273 
274 int
275 proxy_access_log (struct timeval *start_time, int client_ip_addr, const char *dbname, const char *dbuser, bool accepted)
276 {
277  char *access_log_file;
278  char *script = NULL;
279  char *clt_ip;
280  char *clt_appl = NULL;
281  struct tm ct1, ct2;
282  time_t t1, t2;
283  char *p;
284  char err_str[4];
285  struct timeval end_time;
286 
287  access_log_file = proxy_info_p->access_log_file;
288 
289  gettimeofday (&end_time, NULL);
290 
291  t1 = start_time->tv_sec;
292  t2 = end_time.tv_sec;
293 #if defined (WINDOWS)
294  if (localtime_s (&ct1, &t1) != 0 || localtime_s (&ct2, &t2) != 0)
295 #else /* !WINDOWS */
296  if (localtime_r (&t1, &ct1) == NULL || localtime_r (&t2, &ct2) == NULL)
297 #endif /* !WINDOWS */
298  {
299  return -1;
300  }
301  ct1.tm_year += 1900;
302  ct2.tm_year += 1900;
303 
304  if (proxy_info_p->proxy_access_log_reset)
305  {
306  if (access_log_fp != NULL)
307  {
308  fclose (access_log_fp);
310  }
311  proxy_info_p->proxy_access_log_reset = 0;
312  }
313 
314  if (access_log_fp == NULL)
315  {
316  access_log_fp = log_open (access_log_file);
317  if (access_log_fp == NULL)
318  {
319  return -1;
320  }
321  proxy_info_p->proxy_access_log_reset = 0;
322  }
323 
324  if (script == NULL)
325  script = (char *) "-";
326  if (clt_appl == NULL || clt_appl[0] == '\0')
327  clt_appl = (char *) "-";
328 
329  clt_ip = ut_uchar2ipstr ((unsigned char *) (&client_ip_addr));
330 
331  for (p = clt_appl; *p; p++)
332  {
333  if (*p == ' ' || *p == '\t' || *p == '\n' || *p == '\r')
334  *p = '_';
335  }
336 
337 #ifdef CAS_ERROR_LOG
338  if (error_file_offset >= 0)
339  sprintf (err_str, "ERR");
340  else
341 #endif
342  sprintf (err_str, "-");
343 
344  fprintf (access_log_fp,
345  "%s %s %s %d.%03d %d.%03d %02d/%02d/%02d %02d:%02d:%02d ~ "
346  "%02d/%02d/%02d %02d:%02d:%02d %d %s %d %s %s %s\n", clt_ip, clt_appl, script, (int) start_time->tv_sec,
347  (int) (start_time->tv_usec / 1000), (int) end_time.tv_sec, (int) (end_time.tv_usec / 1000), ct1.tm_year,
348  ct1.tm_mon + 1, ct1.tm_mday, ct1.tm_hour, ct1.tm_min, ct1.tm_sec, ct2.tm_year, ct2.tm_mon + 1, ct2.tm_mday,
349  ct2.tm_hour, ct2.tm_min, ct2.tm_sec, (int) getpid (), err_str, -1, dbname, dbuser,
350  ((accepted) ? "" : " : rejected"));
351  fflush (access_log_fp);
352 
353  return (end_time.tv_sec - start_time->tv_sec);
354 }
355 
356 void
358 {
359  if (access_log_fp != NULL)
360  {
361  fclose (access_log_fp);
363  }
364 }
365 
366 static FILE *
367 log_open (char *log_file_name)
368 {
369  FILE *fp;
370  int ret;
371  char *tmp_dirname;
372  char *tmp_filename;
373 
374  if (log_file_name == NULL)
375  return NULL;
376 
377  fp = fopen (log_file_name, "a");
378  if (fp == NULL)
379  {
380  if (errno == ENOENT)
381  {
382  tmp_filename = strdup (log_file_name);
383  if (tmp_filename == NULL)
384  {
385  return NULL;
386  }
387  tmp_dirname = dirname (tmp_filename);
388  ret = mkdir (tmp_dirname, 0777);
389  free (tmp_filename);
390  if (ret == 0)
391  {
392  fp = fopen (log_file_name, "a");
393  if (fp == NULL)
394  {
395  return NULL;
396  }
397  }
398  else
399  {
400  return NULL;
401  }
402  }
403  else
404  {
405  return NULL;
406  }
407  }
408  return fp;
409 }
char access_log_file[CONF_LOG_FILE_LEN]
Definition: broker_shm.h:492
char * dirname(const char *path)
Definition: porting.c:1066
static char * dbuser
char proxy_log_dir[CONF_LOG_FILE_LEN]
Definition: broker_shm.h:600
#define PROXY_LOG_BUFFER_SIZE
#define BROKER_PATH_MAX
Definition: broker_config.h:91
int proxy_access_log(struct timeval *start_time, int client_ip_addr, const char *dbname, const char *dbuser, bool accepted)
int ut_time_string(char *buf, struct timeval *time_val)
Definition: broker_util.c:421
char broker_name[BROKER_NAME_LEN]
Definition: broker_shm.h:588
static FILE * log_fp
static void proxy_log_reset(void)
static char * make_proxy_log_filename(char *filepath_buf, size_t buf_size, const char *br_name, int proxy_index)
static const char * proxy_log_level_str[]
#define assert(x)
static void proxy_log_backup(void)
static FILE * log_open(char *log_file_name)
T_SHM_APPL_SERVER * shm_as_p
Definition: shard_proxy.c:43
#define NULL
Definition: freelistheap.h:34
int proxy_log_get_level(void)
static char * dbname
static FILE * access_log_fp
static struct timeval start_time
int proxy_access_log_reset
Definition: broker_shm.h:486
int proxy_log_reset
Definition: broker_shm.h:485
void proxy_access_log_close(void)
void proxy_log_open(char *br_name, int proxy_index)
static char log_filepath[BROKER_PATH_MAX]
void proxy_log_close(void)
char * strdup(const char *str)
Definition: porting.c:901
void proxy_log_end(void)
char * ut_uchar2ipstr(unsigned char *ip_addr)
Definition: cas_util.c:43
T_PROXY_INFO * proxy_info_p
Definition: shard_proxy.c:48
static void proxy_log_write_internal(int level, char *svc_code, bool do_flush, const char *fmt, va_list ap)
T_SHM_PROXY * shm_proxy_p
int proxy_id
Definition: shard_proxy.c:45
const char ** p
Definition: dynamic_load.c:945
void proxy_log_write(int level, char *svc_code, const char *fmt,...)
int cur_proxy_log_mode
Definition: broker_shm.h:464