CUBRID Engine  latest
cas_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  * cas_log.c -
22  */
23 
24 #ident "$Id$"
25 
26 #include <stdio.h>
27 #include <stdarg.h>
28 #include <stdlib.h>
29 #include <time.h>
30 #include <string.h>
31 #include <errno.h>
32 #if defined(WINDOWS)
33 #include <sys/timeb.h>
34 #include <process.h>
35 #include <io.h>
36 #else
37 #include <unistd.h>
38 #include <sys/time.h>
39 #endif
40 #include <assert.h>
41 
42 #include "porting.h"
43 #include "cas_common.h"
44 #include "cas_log.h"
45 #include "cas_util.h"
46 #include "broker_config.h"
47 #include "cas.h"
48 #include "cas_execute.h"
49 
50 #include "broker_env_def.h"
51 #include "broker_filename.h"
52 #include "broker_util.h"
53 #if !defined(CAS_FOR_ORACLE) && !defined(CAS_FOR_MYSQL)
54 #include "dbi.h"
55 #include "cas_db_inc.h"
56 #endif
57 
58 #if defined(WINDOWS)
59 typedef int mode_t;
60 #endif /* WINDOWS */
61 
62 #define CAS_LOG_BUFFER_SIZE (8192)
63 #define SQL_LOG_BUFFER_SIZE 163840
64 #define ACCESS_LOG_IS_DENIED_TYPE(T) ((T)==ACL_REJECTED)
65 
66 static const char *get_access_log_type_string (ACCESS_LOG_TYPE type);
67 static char cas_log_buffer[CAS_LOG_BUFFER_SIZE]; /* 8K buffer */
69 
70 static char *make_sql_log_filename (T_CUBRID_FILE_ID fid, char *filename_buf, size_t buf_size, const char *br_name);
71 static void cas_log_backup (T_CUBRID_FILE_ID fid);
72 static void cas_log_write_and_set_savedpos (FILE * log_fp, const char *fmt, ...);
73 
74 
75 #if defined (ENABLE_UNUSED_FUNCTION)
76 static void cas_log_rename (int run_time, time_t cur_time, char *br_name, int as_index);
77 #endif
78 static void cas_log_write_internal (FILE * fp, struct timeval *log_time, unsigned int seq_num, bool do_flush,
79  const char *fmt, va_list ap);
80 static void cas_log_write2_internal (FILE * fp, bool do_flush, const char *fmt, va_list ap);
81 
82 static FILE *access_log_open (char *log_file_name);
83 static bool cas_log_begin_hang_check_time (void);
84 static void cas_log_end_hang_check_time (bool is_prev_time_set);
85 static void cas_log_write_query_string_internal (char *query, int size, bool newline);
86 
87 #ifdef CAS_ERROR_LOG
88 static int error_file_offset;
89 static char cas_log_error_flag;
90 #endif
91 static FILE *log_fp = NULL, *slow_log_fp = NULL;
93 static INT64 saved_log_fpos = 0;
94 
95 static size_t cas_fwrite (const void *ptr, size_t size, size_t nmemb, FILE * stream);
96 static INT64 cas_ftell (FILE * stream);
97 static int cas_fseek (FILE * stream, INT64 offset, int whence);
98 static FILE *cas_fopen (const char *path, const char *mode);
99 #if defined (WINDOWS)
100 static FILE *cas_fopen_and_lock (const char *path, const char *mode);
101 #endif
102 static int cas_fclose (FILE * fp);
103 static int cas_ftruncate (int fd, off_t length);
104 static int cas_fflush (FILE * stream);
105 static int cas_fileno (FILE * stream);
106 static int cas_fprintf (FILE * stream, const char *format, ...);
107 static int cas_fputc (int c, FILE * stream);
108 static int cas_unlink (const char *pathname);
109 static int cas_rename (const char *oldpath, const char *newpath);
110 static int cas_mkdir (const char *pathname, mode_t mode);
111 static void access_log_backup (char *access_log_file, struct tm *ct);
112 
113 static char *
114 make_sql_log_filename (T_CUBRID_FILE_ID fid, char *filename_buf, size_t buf_size, const char *br_name)
115 {
116 #ifndef LIBCAS_FOR_JSP
117  char dirname[BROKER_PATH_MAX];
118  int ret = 0;
119 
120  assert (filename_buf != NULL);
121 
122  get_cubrid_file (fid, dirname, BROKER_PATH_MAX);
123  switch (fid)
124  {
125  case FID_SQL_LOG_DIR:
126  if (cas_shard_flag == ON)
127  {
128  ret = snprintf (filename_buf, buf_size, "%s%s_%d_%d_%d.sql.log", dirname, br_name, shm_proxy_id + 1,
130  }
131  else
132  {
133  ret = snprintf (filename_buf, buf_size, "%s%s_%d.sql.log", dirname, br_name, shm_as_index + 1);
134  }
135  break;
136  case FID_SLOW_LOG_DIR:
137  if (cas_shard_flag == ON)
138  {
139  ret = snprintf (filename_buf, buf_size, "%s%s_%d_%d_%d.slow.log", dirname, br_name, shm_proxy_id + 1,
141  }
142  else
143  {
144  ret = snprintf (filename_buf, buf_size, "%s%s_%d.slow.log", dirname, br_name, shm_as_index + 1);
145  }
146  break;
147  default:
148  assert (0);
149  ret = snprintf (filename_buf, buf_size, "unknown.log");
150  break;
151  }
152  if (ret < 0)
153  {
154  assert (false);
155  filename_buf[0] = '\0';
156  }
157  return filename_buf;
158 #endif /* LIBCAS_FOR_JSP */
159  return NULL;
160 }
161 
162 void
163 cas_log_open (char *br_name)
164 {
165 #ifndef LIBCAS_FOR_JSP
166  if (log_fp != NULL)
167  {
168  cas_log_close (true);
169  }
170 
172  {
173  if (br_name != NULL)
174  {
176  {
178  }
179 
181  }
182 
183  /* note: in "a+" mode, output is always appended */
184  log_fp = cas_fopen (log_filepath, "r+");
185  if (log_fp != NULL)
186  {
187  cas_fseek (log_fp, 0, SEEK_END);
189  }
190  else
191  {
192  log_fp = cas_fopen (log_filepath, "w");
193  saved_log_fpos = 0;
194  }
195 
196  if (log_fp)
197  {
198  setvbuf (log_fp, sql_log_buffer, _IOFBF, SQL_LOG_BUFFER_SIZE);
199  }
200  }
201  else
202  {
203  log_fp = NULL;
204  saved_log_fpos = 0;
205  }
206  as_info->cas_log_reset = 0;
207 #endif /* LIBCAS_FOR_JSP */
208 }
209 
210 void
211 cas_log_reset (char *br_name)
212 {
213 #ifndef LIBCAS_FOR_JSP
214  if (as_info->cas_log_reset)
215  {
216  if (log_fp != NULL)
217  {
218  cas_log_close (true);
219  }
221  {
223  }
224 
226  {
227  cas_log_open (br_name);
228  }
229  }
230 #endif /* LIBCAS_FOR_JSP */
231 }
232 
233 void
235 {
236 #ifndef LIBCAS_FOR_JSP
237  if (log_fp != NULL)
238  {
239  if (flag)
240  {
241  cas_fseek (log_fp, saved_log_fpos, SEEK_SET);
243  }
244  cas_fclose (log_fp);
245  log_fp = NULL;
246  saved_log_fpos = 0;
247  }
248 #endif /* LIBCAS_FOR_JSP */
249 }
250 
251 static void
253 {
254  char backup_filepath[BROKER_PATH_MAX];
255  char *filepath = NULL;
256 
257  switch (fid)
258  {
259  case FID_SQL_LOG_DIR:
260  assert (log_filepath[0] != '\0');
261  filepath = log_filepath;
262  break;
263  case FID_SLOW_LOG_DIR:
264  assert (slow_log_filepath[0] != '\0');
265  filepath = slow_log_filepath;
266  break;
267  default:
268  assert (0);
269  return;
270  }
271 
272  if (snprintf (backup_filepath, BROKER_PATH_MAX, "%s.bak", filepath) < 0)
273  {
274  assert (false);
275  return;
276  }
277  cas_unlink (backup_filepath);
278  cas_rename (filepath, backup_filepath);
279 }
280 
281 static void
282 cas_log_write_and_set_savedpos (FILE * log_fp, const char *fmt, ...)
283 {
284  va_list ap;
285 
286  if (log_fp == NULL)
287  {
288  return;
289  }
290 
291  va_start (ap, fmt);
292  cas_log_write_internal (log_fp, NULL, 0, false, fmt, ap);
293  va_end (ap);
294 
295  cas_fseek (log_fp, saved_log_fpos, SEEK_SET);
296 
297  return;
298 }
299 
300 #if defined (ENABLE_UNUSED_FUNCTION)
301 static void
302 cas_log_rename (int run_time, time_t cur_time, char *br_name, int as_index)
303 {
304  char new_filepath[BROKER_PATH_MAX];
305  struct tm tmp_tm;
306 
307  assert (log_filepath[0] != '\0');
308 
309  localtime_r (&cur_time, &tmp_tm);
310  tmp_tm.tm_year += 1900;
311 
312  snprintf (new_filepath, BROKER_PATH_MAX, "%s.%02d%02d%02d%02d%02d.%d", log_filepath, tmp_tm.tm_mon + 1,
313  tmp_tm.tm_mday, tmp_tm.tm_hour, tmp_tm.tm_min, tmp_tm.tm_sec, run_time);
314  cas_rename (log_filepath, new_filepath);
315 }
316 #endif /* ENABLE_UNUSED_FUNCTION */
317 
318 void
319 cas_log_end (int mode, int run_time_sec, int run_time_msec)
320 {
321 #ifndef LIBCAS_FOR_JSP
323  {
325  }
326 
327  if (log_fp != NULL)
328  {
329  bool abandon = false;
330 
331  /* 'mode' will be either ALL, ERROR, or TIMEOUT */
332  switch (mode)
333  {
334  case SQL_LOG_MODE_ALL:
335  /* if mode == ALL, write log regardless sql_log_mode */
336  break;
337  case SQL_LOG_MODE_ERROR:
338  /* if mode == ERROR, write log if sql_log_mode == ALL || ERROR || NOTICE */
340  {
341  abandon = true;
342  }
343  break;
345  /* if mode == TIMEOUT, write log if sql_log_mode == ALL || TIMEOUT || NOTICE */
347  {
348  abandon = true;
349  }
350  /* if mode == TIMEOUT and sql_log_mode == TIMEOUT || NOTICE, check if it timed out */
353  {
354  /* check timeout */
355  if ((run_time_sec * 1000 + run_time_msec) < shm_appl->long_transaction_time)
356  {
357  abandon = true;
358  }
359  }
360  break;
361  /* if mode == NONE, write log if sql_log_mode == ALL */
362  case SQL_LOG_MODE_NONE:
364  {
365  abandon = true;
366  }
367  break;
368  case SQL_LOG_MODE_NOTICE:
369  default:
370  /* mode NOTICE or others are unexpected values; do not write log */
371  abandon = true;
372  break;
373  }
374 
375  if (abandon)
376  {
377  cas_log_write_and_set_savedpos (log_fp, "%s", "END OF LOG\n\n");
378  }
379  else
380  {
381  if (run_time_sec >= 0 && run_time_msec >= 0)
382  {
383  cas_log_write (0, false, "*** elapsed time %d.%03d\n", run_time_sec, run_time_msec);
384  }
386 
387  if ((saved_log_fpos / 1000) > shm_appl->sql_log_max_size)
388  {
389  cas_log_close (true);
391  cas_log_open (NULL);
392  }
393  else
394  {
395  cas_log_write_and_set_savedpos (log_fp, "%s", "END OF LOG\n\n");
396  }
397  }
398  }
399 #endif /* LIBCAS_FOR_JSP */
400 }
401 
402 static void
403 cas_log_write_internal (FILE * fp, struct timeval *log_time, unsigned int seq_num, bool do_flush, const char *fmt,
404  va_list ap)
405 {
406  char *buf, *p;
407  int len, n;
408 
409  p = buf = cas_log_buffer;
410  len = CAS_LOG_BUFFER_SIZE;
411  n = ut_time_string (p, log_time);
412  len -= n;
413  p += n;
414 
415  if (len > 0)
416  {
417  n = snprintf (p, len, " (%u) ", seq_num);
418  len -= n;
419  p += n;
420  if (len > 0)
421  {
422  n = vsnprintf (p, len, fmt, ap);
423  if (n >= len)
424  {
425  /* string is truncated and trailing '\0' is included */
426  n = len - 1;
427  }
428  len -= n;
429  p += n;
430  }
431  }
432 
433  cas_fwrite (buf, (p - buf), 1, fp);
434 
435  if (do_flush == true)
436  {
437  cas_fflush (fp);
438  }
439 }
440 
441 void
442 cas_log_write_nonl (unsigned int seq_num, bool unit_start, const char *fmt, ...)
443 {
444 #ifndef LIBCAS_FOR_JSP
446  {
448  }
449 
450  if (log_fp != NULL)
451  {
452  va_list ap;
453 
454  if (unit_start)
455  {
457  }
458  va_start (ap, fmt);
460  va_end (ap);
461  }
462 #endif /* LIBCAS_FOR_JSP */
463 }
464 
465 static void
466 cas_log_query_cancel (int dummy, ...)
467 {
468 #ifndef LIBCAS_FOR_JSP
469  va_list ap;
470  const char *fmt;
471  char buf[LINE_MAX];
472  bool log_mode;
473  struct timeval tv;
474 
475  if (log_fp == NULL || query_cancel_flag != 1)
476  {
477  return;
478  }
479 
480  tv.tv_sec = query_cancel_time / 1000;
481  tv.tv_usec = (query_cancel_time % 1000) * 1000;
482 
484  {
485  char ip_str[16];
486  ut_get_ipv4_string (ip_str, 16, as_info->cas_clt_ip);
487  fmt = "query_cancel client ip %s port %u";
488  snprintf (buf, LINE_MAX, fmt, ip_str, as_info->cas_clt_port);
489  }
490  else
491  {
492  snprintf (buf, LINE_MAX, "query_cancel");
493  }
494 
496  va_start (ap, dummy);
497  cas_log_write_internal (log_fp, &tv, 0, log_mode, buf, ap);
498  va_end (ap);
499  cas_fputc ('\n', log_fp);
500 
501  query_cancel_flag = 0;
502 #endif /* LIBCAS_FOR_JSP */
503 }
504 
505 void
506 cas_log_write (unsigned int seq_num, bool unit_start, const char *fmt, ...)
507 {
508 #ifndef LIBCAS_FOR_JSP
510  {
512  }
513 
515 
516  if (log_fp != NULL)
517  {
518  va_list ap;
519 
520  if (unit_start)
521  {
523  }
524  va_start (ap, fmt);
526  va_end (ap);
527  cas_fputc ('\n', log_fp);
528  }
529 #endif /* LIBCAS_FOR_JSP */
530 }
531 
532 void
533 cas_log_write_and_end (unsigned int seq_num, bool unit_start, const char *fmt, ...)
534 {
535 #ifndef LIBCAS_FOR_JSP
537  {
539  }
540 
541  if (log_fp != NULL)
542  {
543  va_list ap;
544 
545  if (unit_start)
546  {
548  }
549  va_start (ap, fmt);
551  va_end (ap);
552  cas_fputc ('\n', log_fp);
553  cas_log_end (SQL_LOG_MODE_ALL, -1, -1);
554  }
555 #endif /* LIBCAS_FOR_JSP */
556 }
557 
558 static void
559 cas_log_write2_internal (FILE * fp, bool do_flush, const char *fmt, va_list ap)
560 {
561  char *buf, *p;
562  int len, n;
563 
564  p = buf = cas_log_buffer;
565  len = CAS_LOG_BUFFER_SIZE;
566  n = vsnprintf (p, len, fmt, ap);
567  if (n >= len)
568  {
569  /* string is truncated and trailing '\0' is included */
570  n = len - 1;
571  }
572  len -= n;
573  p += n;
574 
575  cas_fwrite (buf, (p - buf), 1, fp);
576 
577  if (do_flush == true)
578  {
579  cas_fflush (fp);
580  }
581 }
582 
583 void
584 cas_log_write2_nonl (const char *fmt, ...)
585 {
586 #ifndef LIBCAS_FOR_JSP
588  {
590  }
591 
592  if (log_fp != NULL)
593  {
594  va_list ap;
595 
596  va_start (ap, fmt);
598  va_end (ap);
599  }
600 #endif /* LIBCAS_FOR_JSP */
601 }
602 
603 void
604 cas_log_write2 (const char *fmt, ...)
605 {
606 #ifndef LIBCAS_FOR_JSP
608  {
610  }
611 
612  if (log_fp != NULL)
613  {
614  va_list ap;
615 
616  va_start (ap, fmt);
618  va_end (ap);
619  cas_fputc ('\n', log_fp);
620  }
621 #endif /* LIBCAS_FOR_JSP */
622 }
623 
624 void
625 cas_log_write_value_string (char *value, int size)
626 {
627 #ifndef LIBCAS_FOR_JSP
629  {
631  }
632 
633  if (log_fp != NULL)
634  {
635  cas_fwrite (value, size, 1, log_fp);
636  }
637 #endif /* LIBCAS_FOR_JSP */
638 }
639 
640 void
641 cas_log_write_query_string_nonl (char *query, int size)
642 {
643  cas_log_write_query_string_internal (query, size, false);
644 }
645 
646 void
647 cas_log_write_query_string (char *query, int size)
648 {
649  cas_log_write_query_string_internal (query, size, true);
650 }
651 
652 static void
653 cas_log_write_query_string_internal (char *query, int size, bool newline)
654 {
655 #ifndef LIBCAS_FOR_JSP
657  {
659  }
660 
661  if (log_fp != NULL && query != NULL)
662  {
663  char *s;
664 
665  for (s = query; *s; s++)
666  {
667  if (*s == '\n' || *s == '\r')
668  {
669  cas_fputc (' ', log_fp);
670  }
671  else
672  {
673  cas_fputc (*s, log_fp);
674  }
675  }
676 
677  if (newline)
678  {
679  fputc ('\n', log_fp);
680  }
681  }
682 #endif /* LIBCAS_FOR_JSP */
683 }
684 
685 void
686 cas_log_write_client_ip (const unsigned char *ip_addr)
687 {
688 #ifndef LIBCAS_FOR_JSP
689  char client_ip_str[16];
690 
691  if (ip_addr != NULL && *((int *) ip_addr) != 0)
692  {
693  ut_get_ipv4_string (client_ip_str, sizeof (client_ip_str), ip_addr);
694  cas_log_write_and_end (0, false, "CLIENT IP %s", client_ip_str);
695  }
696 #endif
697 }
698 
699 #if !defined (NDEBUG)
700 void
701 cas_log_debug (const char *file_name, const int line_no, const char *fmt, ...)
702 {
703 #if 0
704 #ifndef LIBCAS_FOR_JSP
705  if (log_fp != NULL)
706  {
707  char buf[LINE_MAX], *p;
708  int len, n;
709  va_list ap;
710 
711  va_start (ap, fmt);
712  p = buf;
713  len = LINE_MAX;
714  n = ut_time_string (p);
715  len -= n;
716  p += n;
717  if (len > 0)
718  {
719  n = snprintf (p, len, " (debug) file %s line %d ", file_name, line_no);
720  len -= n;
721  p += n;
722  if (len > 0)
723  {
724  n = vsnprintf (p, len, fmt, ap);
725  len -= n;
726  p += n;
727  }
728  }
729  cas_fwrite (buf, (p - buf), 1, log_fp);
730  cas_fputc ('\n', log_fp);
731  va_end (ap);
732  }
733 #endif /* LIBCAS_FOR_JSP */
734 #endif
735 }
736 #endif
737 
738 #ifdef CAS_ERROR_LOG
739 
740 #if defined (ENABLE_UNUSED_FUNCTION)
741 void
742 cas_error_log (int err_code, char *err_msg_str, int client_ip_addr)
743 {
744 #ifndef LIBCAS_FOR_JSP
745  FILE *fp;
746  char *err_log_file = shm_appl->error_log_file;
747  char *script_file = getenv (PATH_INFO_ENV_STR);
748  time_t t = time (NULL);
749  struct tm ct1;
750  char err_code_str[12];
751  char *lastcmd = "";
752  char *ip_str;
753 
754  localtime_r (&t, &ct1);
755  ct1.tm_year += 1900;
756 
757  fp = access_log_open (err_log_file);
758  if (fp == NULL)
759  {
760  return;
761  }
762 
763 #ifdef CAS_ERROR_LOG
764  error_file_offset = cas_ftell (fp);
765 #endif
766 
767  if (script_file == NULL)
768  script_file = "";
769  sprintf (err_code_str, "%d", err_code);
770  ip_str = ut_uchar2ipstr ((unsigned char *) (&client_ip_addr));
771 
772  cas_fprintf (fp, "[%d] %s %s %d/%d/%d %d:%d:%d %d\n%s:%s\ncmd:%s\n", (int) getpid (), ip_str, script_file,
773  ct1.tm_year, ct1.tm_mon + 1, ct1.tm_mday, ct1.tm_hour, ct1.tm_min, ct1.tm_sec,
774  (int) (strlen (err_code_str) + strlen (err_msg_str) + 1), err_code_str, err_msg_str, lastcmd);
775  cas_fclose (fp);
776 
777  cas_log_error_flag = 1;
778 #endif /* LIBCAS_FOR_JSP */
779 }
780 #endif /* ENABLE_UNUSED_FUNCTION */
781 #endif
782 
783 int
784 cas_access_log (struct timeval *start_time, int as_index, int client_ip_addr, char *dbname, char *dbuser,
785  ACCESS_LOG_TYPE log_type)
786 {
787 #ifndef LIBCAS_FOR_JSP
788  FILE *fp;
789  char *access_log_file = shm_appl->access_log_file;
790  char clt_ip_str[16];
791  struct tm ct1, ct2;
792  time_t t1, t2;
793  struct timeval end_time;
794  char log_file_buf[PATH_MAX];
795  const char *print_format = "%d %s %04d/%02d/%02d %02d:%02d:%02d %s %s %s %s\n";
796  char session_id_buf[16];
797 
798  gettimeofday (&end_time, NULL);
799 
800  t1 = start_time->tv_sec;
801  t2 = end_time.tv_sec;
802  if (localtime_r (&t1, &ct1) == NULL || localtime_r (&t2, &ct2) == NULL)
803  {
804  return -1;
805  }
806  ct1.tm_year += 1900;
807  ct2.tm_year += 1900;
808 
809  if (ACCESS_LOG_IS_DENIED_TYPE (log_type))
810  {
811  int n;
812  n = snprintf (log_file_buf, PATH_MAX, "%s%s", shm_appl->access_log_file, ACCESS_LOG_DENIED_FILENAME_POSTFIX);
813  if (n >= PATH_MAX)
814  {
815  return -1;
816  }
817 
818  access_log_file = log_file_buf;
819  }
820 
821  fp = access_log_open (access_log_file);
822  if (fp == NULL)
823  {
824  return -1;
825  }
826 
827  fseek (fp, 0, SEEK_END);
828  if ((ftell (fp) / ONE_K) > shm_appl->access_log_max_size)
829  {
830  time_t cur_time = time (NULL);
831  struct tm ct;
832 
833  if (localtime_r (&cur_time, &ct) != NULL)
834  {
835  ct.tm_year += 1900;
836 
837  cas_fclose (fp);
838 
839  access_log_backup (access_log_file, &ct);
840 
841  fp = access_log_open (access_log_file);
842  if (fp == NULL)
843  {
844  return -1;
845  }
846  }
847  }
848 
849  ut_get_ipv4_string (clt_ip_str, sizeof (clt_ip_str), (unsigned char *) (&client_ip_addr));
850 
851  session_id_buf[0] = '\0';
852 
853 #if !defined(CAS_FOR_ORACLE) && !defined(CAS_FOR_MYSQL)
854  if (!ACCESS_LOG_IS_DENIED_TYPE (log_type))
855  {
856  sprintf (session_id_buf, "%u", db_get_session_id ());
857  }
858 #endif
859 
860  cas_fprintf (fp, print_format, as_index + 1, clt_ip_str, ct1.tm_year, ct1.tm_mon + 1, ct1.tm_mday, ct1.tm_hour,
861  ct1.tm_min, ct1.tm_sec, dbname, dbuser, get_access_log_type_string (log_type), session_id_buf);
862 
863  cas_fclose (fp);
864  return (end_time.tv_sec - start_time->tv_sec);
865 #else /* LIBCAS_FOR_JSP */
866  return 0;
867 #endif /* !LIBCAS_FOR_JSP */
868 }
869 
870 void
871 cas_log_query_info_init (int id, char is_only_query_plan)
872 {
873 #if !defined(LIBCAS_FOR_JSP) && !defined(CAS_FOR_ORACLE) && !defined(CAS_FOR_MYSQL)
874  char *plan_dump_filename;
875 
876  plan_dump_filename = cas_log_query_plan_file (id);
877  cas_unlink (plan_dump_filename);
878  db_query_plan_dump_file (plan_dump_filename);
879 
880  if (is_only_query_plan)
881  {
883  }
884  else
885  {
887  }
888 #endif /* !LIBCAS_FOR_JSP && !CAS_FOR_ORACLE && !CAS_FOR_MYSQL */
889 }
890 
891 char *
893 {
894 #ifndef LIBCAS_FOR_JSP
895  static char plan_file_name[BROKER_PATH_MAX];
896  char dirname[BROKER_PATH_MAX];
898  if (snprintf (plan_file_name, BROKER_PATH_MAX - 1, "%s/%d.%d.plan", dirname, (int) getpid (), id) < 0)
899  {
900  assert (false);
901  return NULL;
902  }
903  return plan_file_name;
904 #else /* LIBCAS_FOR_JSP */
905  return NULL;
906 #endif /* !LIBCAS_FOR_JSP */
907 }
908 
909 static FILE *
910 access_log_open (char *log_file_name)
911 {
912  FILE *fp;
913  int ret;
914  char *tmp_dirname;
915  char *tmp_filename;
916 
917  if (log_file_name == NULL)
918  return NULL;
919 
920 #if defined (WINDOWS)
921  fp = cas_fopen_and_lock (log_file_name, "a");
922 #else
923  /* In case of Linux and solaris..., Openning a file in append mode guarantees subsequent write operations to occur at
924  * ent-of-file. So we don't need to lock to the opened file. */
925  fp = cas_fopen (log_file_name, "a");
926 #endif
927 
928  if (fp == NULL)
929  {
930  if (errno == ENOENT)
931  {
932  tmp_filename = strdup (log_file_name);
933  if (tmp_filename == NULL)
934  {
935  return NULL;
936  }
937  tmp_dirname = dirname (tmp_filename);
938  ret = cas_mkdir (tmp_dirname, 0777);
939  free (tmp_filename);
940  if (ret == 0)
941  {
942 #if defined (WINDOWS)
943  fp = cas_fopen_and_lock (log_file_name, "a");
944 #else
945  fp = cas_fopen (log_file_name, "a");
946 #endif
947  if (fp == NULL)
948  {
949  return NULL;
950  }
951  }
952  else
953  {
954  return NULL;
955  }
956  }
957  else
958  {
959  return NULL;
960  }
961  }
962  return fp;
963 }
964 
965 void
966 cas_slow_log_open (char *br_name)
967 {
968 #ifndef LIBCAS_FOR_JSP
969  if (slow_log_fp != NULL)
970  {
972  }
973 
975  {
976  if (br_name != NULL)
977  {
979  {
981  }
982 
984  }
985 
986  /* note: in "a+" mode, output is always appended */
988  }
989  else
990  {
991  slow_log_fp = NULL;
992  }
994 #endif /* LIBCAS_FOR_JSP */
995 }
996 
997 void
998 cas_slow_log_reset (char *br_name)
999 {
1000 #ifndef LIBCAS_FOR_JSP
1002  {
1003  if (slow_log_fp != NULL)
1004  {
1005  cas_slow_log_close ();
1006  }
1008  {
1010  }
1011 
1013  {
1014  cas_slow_log_open (br_name);
1015  }
1016  }
1017 #endif /* LIBCAS_FOR_JSP */
1018 }
1019 
1020 void
1022 {
1023 #ifndef LIBCAS_FOR_JSP
1024  if (slow_log_fp != NULL)
1025  {
1027  slow_log_fp = NULL;
1028  }
1029 #endif /* LIBCAS_FOR_JSP */
1030 }
1031 
1032 void
1034 {
1035 #ifndef LIBCAS_FOR_JSP
1037  {
1039  }
1040 
1041  if (slow_log_fp != NULL)
1042  {
1043  long slow_log_fpos;
1044  slow_log_fpos = cas_ftell (slow_log_fp);
1045 
1046  if ((slow_log_fpos / 1000) > shm_appl->sql_log_max_size)
1047  {
1048  cas_slow_log_close ();
1051  }
1052  else
1053  {
1054  cas_fputc ('\n', slow_log_fp);
1056  }
1057  }
1058 #endif /* LIBCAS_FOR_JSP */
1059 }
1060 
1061 void
1062 cas_slow_log_write_and_end (struct timeval *log_time, unsigned int seq_num, const char *fmt, ...)
1063 {
1064 #ifndef LIBCAS_FOR_JSP
1066  {
1068  }
1069 
1070  if (slow_log_fp != NULL)
1071  {
1072  va_list ap;
1073 
1074  va_start (ap, fmt);
1075  cas_log_write_internal (slow_log_fp, log_time, seq_num, false, fmt, ap);
1076  va_end (ap);
1077 
1078  cas_slow_log_end ();
1079  }
1080 
1081 #endif /* LIBCAS_FOR_JSP */
1082 }
1083 
1084 void
1085 cas_slow_log_write (struct timeval *log_time, unsigned int seq_num, bool unit_start, const char *fmt, ...)
1086 {
1087 #ifndef LIBCAS_FOR_JSP
1089  {
1091  }
1092 
1093  if (slow_log_fp != NULL)
1094  {
1095  va_list ap;
1096 
1097  va_start (ap, fmt);
1098  cas_log_write_internal (slow_log_fp, log_time, seq_num, false, fmt, ap);
1099  va_end (ap);
1100  }
1101 #endif /* LIBCAS_FOR_JSP */
1102 }
1103 
1104 void
1105 cas_slow_log_write2 (const char *fmt, ...)
1106 {
1107 #ifndef LIBCAS_FOR_JSP
1109  {
1111  }
1112 
1113  if (slow_log_fp != NULL)
1114  {
1115  va_list ap;
1116 
1117  va_start (ap, fmt);
1118  cas_log_write2_internal (slow_log_fp, false, fmt, ap);
1119  va_end (ap);
1120  }
1121 #endif /* LIBCAS_FOR_JSP */
1122 }
1123 
1124 void
1125 cas_slow_log_write_value_string (char *value, int size)
1126 {
1127 #ifndef LIBCAS_FOR_JSP
1129  {
1131  }
1132 
1133  if (slow_log_fp != NULL)
1134  {
1135  cas_fwrite (value, size, 1, slow_log_fp);
1136  }
1137 #endif /* LIBCAS_FOR_JSP */
1138 }
1139 
1140 void
1141 cas_slow_log_write_query_string (char *query, int size)
1142 {
1143 #ifndef LIBCAS_FOR_JSP
1145  {
1147  }
1148 
1149  if (slow_log_fp != NULL && query != NULL)
1150  {
1151  char *s;
1152 
1153  for (s = query; *s; s++)
1154  {
1155  if (*s == '\n' || *s == '\r')
1156  {
1157  cas_fputc (' ', slow_log_fp);
1158  }
1159  else
1160  {
1161  cas_fputc (*s, slow_log_fp);
1162  }
1163  }
1164  cas_fputc ('\n', slow_log_fp);
1165  }
1166 #endif /* LIBCAS_FOR_JSP */
1167 }
1168 
1169 static bool
1171 {
1172 #if !defined(LIBCAS_FOR_JSP)
1173  if (cas_shard_flag == OFF)
1174  {
1175 #if defined(CAS_FOR_ORACLE) || defined(CAS_FOR_MYSQL)
1176  bool is_prev_time_set = (as_info->claimed_alive_time > 0);
1177  if (!is_prev_time_set)
1178  {
1180  }
1181  return is_prev_time_set;
1182 #endif /* CAS_FOR_ORACLE || CAS_FOR_MYSQL */
1183  }
1184 #endif /* !LIBCAS_FOR_JSP */
1185  return false;
1186 }
1187 
1188 static void
1189 cas_log_end_hang_check_time (bool is_prev_time_set)
1190 {
1191 #if !defined(LIBCAS_FOR_JSP)
1192  if (cas_shard_flag == OFF)
1193  {
1194 #if defined(CAS_FOR_ORACLE) || defined(CAS_FOR_MYSQL)
1195  if (!is_prev_time_set)
1196  {
1198  }
1199 #endif /* CAS_FOR_ORACLE || CAS_FOR_MYSQL */
1200  }
1201 #endif /* !LIBCAS_FOR_JSP */
1202 }
1203 
1204 static size_t
1205 cas_fwrite (const void *ptr, size_t size, size_t nmemb, FILE * stream)
1206 {
1207  bool is_prev_time_set;
1208  size_t result;
1209 
1210  is_prev_time_set = cas_log_begin_hang_check_time ();
1211  result = fwrite (ptr, size, nmemb, stream);
1212  cas_log_end_hang_check_time (is_prev_time_set);
1213 
1214  return result;
1215 }
1216 
1217 static INT64
1218 cas_ftell (FILE * stream)
1219 {
1220  return ftell (stream);
1221 }
1222 
1223 static int
1224 cas_fseek (FILE * stream, INT64 offset, int whence)
1225 {
1226  bool is_prev_time_set;
1227  int result;
1228 
1229  is_prev_time_set = cas_log_begin_hang_check_time ();
1230  result = fseek (stream, offset, whence);
1231  cas_log_end_hang_check_time (is_prev_time_set);
1232 
1233  return result;
1234 }
1235 
1236 static FILE *
1237 cas_fopen (const char *path, const char *mode)
1238 {
1239  bool is_prev_time_set;
1240  FILE *result;
1241 
1242  is_prev_time_set = cas_log_begin_hang_check_time ();
1243  result = fopen (path, mode);
1244  cas_log_end_hang_check_time (is_prev_time_set);
1245 
1246  return result;
1247 }
1248 
1249 #if defined (WINDOWS)
1250 static FILE *
1251 cas_fopen_and_lock (const char *path, const char *mode)
1252 {
1253 #define MAX_RETRY_COUNT 100
1254  int retry_count;
1255  bool is_prev_time_set;
1256  FILE *result;
1257 
1258  retry_count = 0;
1259  is_prev_time_set = cas_log_begin_hang_check_time ();
1260 
1261 retry:
1262  result = fopen (path, mode);
1263  if (result != NULL)
1264  {
1265  if (lockf (fileno (result), F_TLOCK, 0) < 0)
1266  {
1267  fclose (result);
1268  if (retry_count < MAX_RETRY_COUNT)
1269  {
1270  SLEEP_MILISEC (0, 10);
1271  retry_count++;
1272  goto retry;
1273  }
1274  result = NULL;
1275  }
1276  }
1277  cas_log_end_hang_check_time (is_prev_time_set);
1278 
1279  return result;
1280 }
1281 #endif
1282 
1283 static int
1284 cas_fclose (FILE * fp)
1285 {
1286  bool is_prev_time_set;
1287  int result;
1288 
1289  is_prev_time_set = cas_log_begin_hang_check_time ();
1290  result = fclose (fp);
1291  cas_log_end_hang_check_time (is_prev_time_set);
1292 
1293  return result;
1294 }
1295 
1296 static int
1297 cas_ftruncate (int fd, off_t length)
1298 {
1299  bool is_prev_time_set;
1300  int result;
1301 
1302  is_prev_time_set = cas_log_begin_hang_check_time ();
1303  result = ftruncate (fd, length);
1304  cas_log_end_hang_check_time (is_prev_time_set);
1305 
1306  return result;
1307 }
1308 
1309 static int
1310 cas_fflush (FILE * stream)
1311 {
1312  bool is_prev_time_set;
1313  int result;
1314 
1315  is_prev_time_set = cas_log_begin_hang_check_time ();
1316  result = fflush (stream);
1317  cas_log_end_hang_check_time (is_prev_time_set);
1318 
1319  return result;
1320 
1321 }
1322 
1323 static int
1324 cas_fileno (FILE * stream)
1325 {
1326  bool is_prev_time_set;
1327  int result;
1328 
1329  is_prev_time_set = cas_log_begin_hang_check_time ();
1330  result = fileno (stream);
1331  cas_log_end_hang_check_time (is_prev_time_set);
1332 
1333  return result;
1334 }
1335 
1336 static int
1337 cas_fprintf (FILE * stream, const char *format, ...)
1338 {
1339  bool is_prev_time_set;
1340  int result;
1341  va_list ap;
1342 
1343  va_start (ap, format);
1344 
1345  is_prev_time_set = cas_log_begin_hang_check_time ();
1346  result = vfprintf (stream, format, ap);
1347  cas_log_end_hang_check_time (is_prev_time_set);
1348 
1349  va_end (ap);
1350 
1351  return result;
1352 }
1353 
1354 static int
1355 cas_fputc (int c, FILE * stream)
1356 {
1357  bool is_prev_time_set;
1358  int result;
1359 
1360  is_prev_time_set = cas_log_begin_hang_check_time ();
1361  result = fputc (c, stream);
1362  cas_log_end_hang_check_time (is_prev_time_set);
1363 
1364  return result;
1365 }
1366 
1367 static int
1368 cas_unlink (const char *pathname)
1369 {
1370  bool is_prev_time_set;
1371  int result;
1372 
1373  is_prev_time_set = cas_log_begin_hang_check_time ();
1374  result = unlink (pathname);
1375  cas_log_end_hang_check_time (is_prev_time_set);
1376 
1377  return result;
1378 }
1379 
1380 static int
1381 cas_rename (const char *oldpath, const char *newpath)
1382 {
1383  bool is_prev_time_set;
1384  int result;
1385 
1386  is_prev_time_set = cas_log_begin_hang_check_time ();
1387  result = rename (oldpath, newpath);
1388  cas_log_end_hang_check_time (is_prev_time_set);
1389 
1390  return result;
1391 }
1392 
1393 static int
1394 cas_mkdir (const char *pathname, mode_t mode)
1395 {
1396  bool is_prev_time_set;
1397  int result;
1398 
1399  is_prev_time_set = cas_log_begin_hang_check_time ();
1400  result = mkdir (pathname, mode);
1401  cas_log_end_hang_check_time (is_prev_time_set);
1402 
1403  return result;
1404 }
1405 
1406 static void
1407 access_log_backup (char *access_log_file, struct tm *ct)
1408 {
1409  char cmd_buf[BUFSIZ];
1410 
1411  sprintf (cmd_buf, "%s.%04d%02d%02d%02d%02d%02d", access_log_file, ct->tm_year, ct->tm_mon + 1, ct->tm_mday,
1412  ct->tm_hour, ct->tm_min, ct->tm_sec);
1413  rename (access_log_file, cmd_buf);
1414 }
1415 
1416 static const char *
1418 {
1419 #if !defined(CAS_FOR_ORACLE) && !defined(CAS_FOR_MYSQL)
1420  switch (type)
1421  {
1422  case NEW_CONNECTION:
1423  return "NEW";
1424  case CLIENT_CHANGED:
1425  return "OLD";
1426  case ACL_REJECTED:
1427  return "REJECT";
1428  default:
1429  assert (0);
1430  break;
1431  }
1432 #endif
1433 
1434  return "";
1435 }
#define SLEEP_MILISEC(sec, msec)
Definition: util_func.h:40
static int cas_fileno(FILE *stream)
Definition: cas_log.c:1324
static INT64 cas_ftell(FILE *stream)
Definition: cas_log.c:1218
char * dirname(const char *path)
Definition: porting.c:1066
static void cas_log_query_cancel(int dummy,...)
Definition: cas_log.c:466
static char * dbuser
#define PATH_INFO_ENV_STR
static void cas_log_write2_internal(FILE *fp, bool do_flush, const char *fmt, va_list ap)
Definition: cas_log.c:559
static int cas_ftruncate(int fd, off_t length)
Definition: cas_log.c:1297
static int cas_fflush(FILE *stream)
Definition: cas_log.c:1310
static void access_log_backup(char *access_log_file, struct tm *ct)
Definition: cas_log.c:1407
static void cas_log_write_and_set_savedpos(FILE *log_fp, const char *fmt,...)
Definition: cas_log.c:282
void set_hang_check_time(void)
Definition: cas.c:1488
#define CAS_PROTO_MAKE_VER(VER)
Definition: cas_protocol.h:284
char error_log_file[CONF_LOG_FILE_LEN]
Definition: broker_shm.h:599
void unset_hang_check_time(void)
Definition: cas.c:1505
char * ut_get_ipv4_string(char *ip_str, int len, const unsigned char *ip_addr)
Definition: broker_util.c:474
static int cas_fseek(FILE *stream, INT64 offset, int whence)
Definition: cas_log.c:1224
SESSION_ID db_get_session_id(void)
Definition: db_admin.c:2859
unsigned char cas_clt_ip[4]
Definition: broker_shm.h:323
#define BROKER_PATH_MAX
Definition: broker_config.h:91
void cas_slow_log_open(char *br_name)
Definition: cas_log.c:966
T_BROKER_VERSION clt_version
Definition: broker_shm.h:303
static char log_filepath[BROKER_PATH_MAX]
Definition: cas_log.c:92
static int cas_fputc(int c, FILE *stream)
Definition: cas_log.c:1355
void cas_log_write_nonl(unsigned int seq_num, bool unit_start, const char *fmt,...)
Definition: cas_log.c:442
static INT64 saved_log_fpos
Definition: cas_log.c:93
void cas_slow_log_write_and_end(struct timeval *log_time, unsigned int seq_num, const char *fmt,...)
Definition: cas_log.c:1062
#define CAS_LOG_RESET_REOPEN
Definition: broker_shm.h:122
void set_optimization_level(int level)
Definition: cas_execute.c:9843
static FILE * log_fp
Definition: cas_log.c:91
#define CAS_LOG_RESET_REMOVE
Definition: broker_shm.h:123
void cas_slow_log_end()
Definition: cas_log.c:1033
void cas_slow_log_write_value_string(char *value, int size)
Definition: cas_log.c:1125
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 char cas_log_buffer[CAS_LOG_BUFFER_SIZE]
Definition: cas_log.c:67
INT64 query_cancel_time
Definition: cas.c:161
void cas_log_write_query_string_nonl(char *query, int size)
Definition: cas_log.c:641
static const char * get_access_log_type_string(ACCESS_LOG_TYPE type)
Definition: cas_log.c:1417
char * get_cubrid_file(T_CUBRID_FILE_ID fid, char *buf, size_t len)
static FILE * slow_log_fp
Definition: cas_log.c:91
char query_cancel_flag
Definition: cas.c:162
int shm_proxy_id
Definition: cas.c:154
unsigned short cas_clt_port
Definition: broker_shm.h:324
int cas_shard_flag
Definition: cas.c:143
static bool cas_log_begin_hang_check_time(void)
Definition: cas_log.c:1170
int cas_access_log(struct timeval *start_time, int as_index, int client_ip_addr, char *dbname, char *dbuser, ACCESS_LOG_TYPE log_type)
Definition: cas_log.c:784
#define assert(x)
void cas_log_write_query_string(char *query, int size)
Definition: cas_log.c:647
char * cas_log_query_plan_file(int id)
Definition: cas_log.c:892
void cas_log_write2_nonl(const char *fmt,...)
Definition: cas_log.c:584
static int cas_unlink(const char *pathname)
Definition: cas_log.c:1368
static void cas_log_backup(T_CUBRID_FILE_ID fid)
Definition: cas_log.c:252
static enum scanner_mode mode
void cas_log_end(int mode, int run_time_sec, int run_time_msec)
Definition: cas_log.c:319
static FILE * cas_fopen(const char *path, const char *mode)
Definition: cas_log.c:1237
static int cas_mkdir(const char *pathname, mode_t mode)
Definition: cas_log.c:1394
#define NULL
Definition: freelistheap.h:34
int db_query_plan_dump_file(char *filename)
Definition: db_query.c:3541
static int cas_fprintf(FILE *stream, const char *format,...)
Definition: cas_log.c:1337
#define CAS_LOG_BUFFER_SIZE
Definition: cas_log.c:62
static char * dbname
void cas_slow_log_write_query_string(char *query, int size)
Definition: cas_log.c:1141
void cas_log_write_value_string(char *value, int size)
Definition: cas_log.c:625
static int cas_fclose(FILE *fp)
Definition: cas_log.c:1284
void cas_log_debug(const char *file_name, const int line_no, const char *fmt,...)
Definition: cas_log.c:701
#define SQL_LOG_BUFFER_SIZE
Definition: cas_log.c:63
static char slow_log_filepath[BROKER_PATH_MAX]
Definition: cas_log.c:92
static char sql_log_buffer[SQL_LOG_BUFFER_SIZE]
Definition: cas_log.c:68
ACCESS_LOG_TYPE
Definition: cas_log.h:29
static struct timeval start_time
static T_SHM_APPL_SERVER * shm_appl
Definition: broker.c:311
static void cas_log_write_internal(FILE *fp, struct timeval *log_time, unsigned int seq_num, bool do_flush, const char *fmt, va_list ap)
Definition: cas_log.c:403
int shm_as_index
Definition: cas.c:151
static void cas_log_write_query_string_internal(char *query, int size, bool newline)
Definition: cas_log.c:653
void cas_log_write_client_ip(const unsigned char *ip_addr)
Definition: cas_log.c:686
static int cas_rename(const char *oldpath, const char *newpath)
Definition: cas_log.c:1381
void cas_log_reset(char *br_name)
Definition: cas_log.c:211
static char * make_sql_log_filename(T_CUBRID_FILE_ID fid, char *filename_buf, size_t buf_size, const char *br_name)
Definition: cas_log.c:114
int shm_shard_id
Definition: cas.c:144
void cas_slow_log_reset(char *br_name)
Definition: cas_log.c:998
time_t claimed_alive_time
Definition: broker_shm.h:319
#define ACCESS_LOG_DENIED_FILENAME_POSTFIX
#define MAX_RETRY_COUNT
void cas_log_query_info_init(int id, char is_only_query_plan)
Definition: cas_log.c:871
#define strlen(s1)
Definition: intl_support.c:43
void cas_log_write(unsigned int seq_num, bool unit_start, const char *fmt,...)
Definition: cas_log.c:506
#define ACCESS_LOG_IS_DENIED_TYPE(T)
Definition: cas_log.c:64
void cas_slow_log_write2(const char *fmt,...)
Definition: cas_log.c:1105
void cas_slow_log_write(struct timeval *log_time, unsigned int seq_num, bool unit_start, const char *fmt,...)
Definition: cas_log.c:1085
T_APPL_SERVER_INFO * as_info
Definition: cas.c:153
void cas_log_write_and_end(unsigned int seq_num, bool unit_start, const char *fmt,...)
Definition: cas_log.c:533
#define ONE_K
Definition: porting.h:62
static FILE * access_log_open(char *log_file_name)
Definition: cas_log.c:910
char access_log_file[CONF_LOG_FILE_LEN]
Definition: broker_shm.h:592
char * strdup(const char *str)
Definition: porting.c:901
enum t_cubrid_file_id T_CUBRID_FILE_ID
void set_cubrid_file(T_CUBRID_FILE_ID fid, char *value)
char * ut_uchar2ipstr(unsigned char *ip_addr)
Definition: cas_util.c:43
void cas_log_close(bool flag)
Definition: cas_log.c:234
char slow_log_dir[CONF_LOG_FILE_LEN]
Definition: broker_shm.h:586
void cas_log_write2(const char *fmt,...)
Definition: cas_log.c:604
void cas_slow_log_close()
Definition: cas_log.c:1021
char log_dir[CONF_LOG_FILE_LEN]
Definition: broker_shm.h:585
static size_t cas_fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream)
Definition: cas_log.c:1205
void cas_log_open(char *br_name)
Definition: cas_log.c:163
static void cas_log_end_hang_check_time(bool is_prev_time_set)
Definition: cas_log.c:1189
const char ** p
Definition: dynamic_load.c:945
int shm_shard_cas_id
Definition: cas.c:155