CUBRID Engine  latest
broker_log_top_tran.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  * broker_log_top_tran.c -
22  */
23 
24 #ident "$Id$"
25 
26 #include <stdio.h>
27 #include <errno.h>
28 #include <string.h>
29 #include <stdlib.h>
30 
31 #include "cas_common.h"
32 #include "broker_log_top.h"
33 #include "log_top_string.h"
34 #include "broker_log_util.h"
35 
36 #define TRAN_LOG_MAX_COUNT 1000
37 #define LOG_TOP_RES_FILE_TRAN "log_top.t"
38 
39 typedef struct t_log_info T_LOG_INFO;
40 struct t_log_info
41 {
42  float runtime;
43  char *logstr;
44 };
45 
46 static int log_top (FILE * fp, char *filename, long start_offset, long end_offset);
47 static int info_delete (T_LOG_INFO * info);
48 static void print_result (void);
49 static int info_add (T_LOG_INFO * info, char *start_date, char *end_date);
50 
51 static int info_arr_size = 0;
54 
55 int
56 log_top_tran (int argc, char *argv[], int arg_start)
57 {
58  int i;
59  int error = 0;
60  char *filename;
61  FILE *fp;
62  long start_offset, end_offset;
63 
64  info_arr_size = 0;
65 
66  for (i = arg_start; i < argc; i++)
67  {
68  filename = argv[i];
69  fprintf (stdout, "%s\n", filename);
70 
71 #if defined(WINDOWS)
72  fp = fopen (filename, "rb");
73 #else
74  fp = fopen (filename, "r");
75 #endif
76  if (fp == NULL)
77  {
78  fprintf (stderr, "%s[%s]\n", strerror (errno), filename);
79  return -1;
80  }
81  if (get_file_offset (filename, &start_offset, &end_offset) < 0)
82  {
83  start_offset = end_offset = -1;
84  }
85 
86  error = log_top (fp, filename, start_offset, end_offset);
87  fclose (fp);
88  if (error == LT_INVAILD_VERSION)
89  {
90  return error;
91  }
92  }
93 
94  print_result ();
95 
96  return 0;
97 }
98 
99 static int
100 log_top (FILE * fp, char *filename, long start_offset, long end_offset)
101 {
102  char *linebuf;
103  T_STRING *str_buf = NULL;
104  T_STRING *linebuf_tstr = NULL;
105  int lineno = 0;
106  int is_first = 1;
107  int log_type = 0;
108  char fileinfo_str[1024];
109  char cur_date[DATE_STR_LEN + 1];
110  char start_date[DATE_STR_LEN + 1];
111  char *msg_p;
112 
113  start_date[0] = '\0';
114 
115  str_buf = t_string_make (1);
116  linebuf_tstr = t_string_make (1000);
117  if (str_buf == NULL || linebuf_tstr == NULL)
118  {
119  fprintf (stderr, "malloc error\n");
120  goto error;
121  }
122 
123  if (start_offset != -1)
124  {
125  fseek (fp, start_offset, SEEK_SET);
126  }
127 
128  while (1)
129  {
130  if (end_offset != -1)
131  {
132  if (ftell (fp) > end_offset)
133  {
134  break;
135  }
136  }
137 
138  if (ut_get_line (fp, linebuf_tstr, &linebuf, &lineno) <= 0)
139  {
140  break;
141  }
142 
143  log_type = is_cas_log (linebuf);
144  if (log_type == CAS_LOG_BEGIN_WITH_MONTH)
145  {
146  fprintf (stderr, "invaild version of log file\n");
147  t_string_free (str_buf);
148  t_string_free (linebuf_tstr);
149  return LT_INVAILD_VERSION;
150  }
151  else if (log_type != CAS_LOG_BEGIN_WITH_YEAR)
152  {
153  continue;
154  }
155 
156  if (strncmp (linebuf + 23, "END OF LOG", 10) == 0)
157  {
158  break;
159  }
160 
161  GET_CUR_DATE_STR (cur_date, linebuf);
162  if (start_date[0] == '\0')
163  {
164  strcpy (start_date, cur_date);
165  }
166 
167  if (is_first)
168  {
169  if (linebuf[0] != '\n')
170  {
171  sprintf (fileinfo_str, "%s:%d\n", filename, lineno);
172  t_string_add (str_buf, fileinfo_str, (int) strlen (fileinfo_str));
173  is_first = 0;
174  }
175  }
176 
177  t_string_add (str_buf, linebuf, (int) strlen (linebuf));
178 
179  msg_p = get_msg_start_ptr (linebuf);
180  if (strncmp (msg_p, "***", 3) == 0)
181  {
182  float runtime;
183 
184  if (sscanf (msg_p + 3 + 1, "%*s %*s %f", &runtime) == 1)
185  {
186  T_LOG_INFO tmpinfo;
187  char *log_str;
188  log_str = strdup (t_string_str (str_buf));
189  if (log_str == NULL)
190  {
191  perror ("strdup");
192  goto error;
193  }
194  tmpinfo.runtime = runtime;
195  tmpinfo.logstr = log_str;
196  info_add (&tmpinfo, start_date, cur_date);
197  }
198  t_string_clear (str_buf);
199  is_first = 1;
200  start_date[0] = '\0';
201  }
202  }
203 
204  t_string_free (str_buf);
205  t_string_free (linebuf_tstr);
206 
207  return LT_NO_ERROR;
208 
209 error:
210  t_string_free (str_buf);
211  t_string_free (linebuf_tstr);
212  return LT_OTHER_ERROR;
213 }
214 
215 static void
217 {
218  T_LOG_INFO temp[TRAN_LOG_MAX_COUNT + 1];
219  int i;
220  FILE *fp_t;
221 
222  fp_t = fopen (LOG_TOP_RES_FILE_TRAN, "w");
223  if (fp_t == NULL)
224  {
225  fprintf (stderr, "%s\n", strerror (errno));
226  return;
227  }
228 
229  for (i = 0;; i++)
230  {
231  if (info_delete (&temp[i]) < 0)
232  break;
233  }
234 
235  for (i--; i >= 0; i--)
236  {
237 #if 0
238  fprintf (fp_t, "-----------------------------------------------------\n");
239 #endif
240  fprintf (fp_t, "%s\n", temp[i].logstr);
241  FREE_MEM (temp[i].logstr);
242  }
243 
244  fclose (fp_t);
245 }
246 
247 static int
248 info_add (T_LOG_INFO * info, char *start_date, char *end_date)
249 {
250  int i;
251  T_LOG_INFO temp;
252 
253  if (check_log_time (start_date, end_date) < 0)
254  return 0;
255 
257  {
258  if (info_arr[1].runtime > info->runtime)
259  {
260  FREE_MEM (info->logstr);
261  return 0;
262  }
263  info_delete (&temp);
264  FREE_MEM (temp.logstr);
265  }
266 
267  i = ++info_arr_size;
268  while ((i != 1) && (info->runtime < info_arr[i / 2].runtime))
269  {
270  info_arr[i] = info_arr[i / 2];
271  i /= 2;
272  }
273  info_arr[i] = *info;
274  return 0;
275 }
276 
277 static int
279 {
280  T_LOG_INFO temp;
281  int parent, child;
282 
283  if (info_arr_size <= 0)
284  return -1;
285 
286  if (info)
287  *info = info_arr[1];
288 
289  temp = info_arr[info_arr_size--];
290  parent = 1;
291  child = 2;
292  while (child <= info_arr_size)
293  {
294  if ((child < info_arr_size) && (info_arr[child].runtime > info_arr[child + 1].runtime))
295  child++;
296  if (temp.runtime < info_arr[child].runtime)
297  break;
298  info_arr[parent] = info_arr[child];
299  parent = child;
300  child *= 2;
301  }
302  info_arr[parent] = temp;
303  return 0;
304 }
#define DATE_STR_LEN
#define CAS_LOG_BEGIN_WITH_YEAR
static int info_delete(T_LOG_INFO *info)
int t_string_add(T_STRING *t_str, char *str, int str_len)
char * get_msg_start_ptr(char *linebuf)
int argc
Definition: dynamic_load.c:951
static int info_arr_max_size
void t_string_free(T_STRING *t_str)
static T_LOG_INFO info_arr[TRAN_LOG_MAX_COUNT+1]
static int info_add(T_LOG_INFO *info, char *start_date, char *end_date)
#define LOG_TOP_RES_FILE_TRAN
#define TRAN_LOG_MAX_COUNT
#define CAS_LOG_BEGIN_WITH_MONTH
char * t_string_str(T_STRING *t_str)
int is_cas_log(char *str)
#define NULL
Definition: freelistheap.h:34
#define GET_CUR_DATE_STR(BUF, LINEBUF)
#define FREE_MEM(PTR)
Definition: cas_common.h:58
static int info_arr_size
static int log_top(FILE *fp, char *filename, long start_offset, long end_offset)
static void error(const char *msg)
Definition: gencat.c:331
static void print_result(void)
const char ** argv
Definition: dynamic_load.c:952
#define strlen(s1)
Definition: intl_support.c:43
int i
Definition: dynamic_load.c:954
T_STRING * t_string_make(int init_size)
char * strdup(const char *str)
Definition: porting.c:901
int check_log_time(char *start_date, char *end_date)
int log_top_tran(int argc, char *argv[], int arg_start)
int get_file_offset(char *filename, long *start_offset, long *end_offset)
void t_string_clear(T_STRING *t_str)
int ut_get_line(FILE *fp, T_STRING *t_str, char **out_str, int *lineno)