CUBRID Engine  latest
cas_query_info.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_query_info.c -
22  */
23 
24 #ident "$Id$"
25 
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <errno.h>
29 #include <string.h>
30 #ifdef MT_MODE
31 #include <pthread.h>
32 #endif
33 
34 #include "cas_common.h"
35 #include "cas_query_info.h"
36 #include "broker_log_sql_list.h"
37 #include "broker_log_top.h"
38 
39 #define LOG_TOP_RES_FILE "log_top.res"
40 #define LOG_TOP_Q_FILE "log_top.q"
41 #define LOG_TOP_TAG_FILE "tags"
42 #define LOG_TOP_NE_FILE "log_top.ne"
43 
44 static int sort_func (const void *arg1, const void *arg2);
45 static char *time2str (int t, char *buf);
46 
48 static int num_query_info = 0;
49 
50 #ifdef TEST
51 static T_QUERY_INFO *query_info_arr_ne = NULL;
52 static int num_query_info_ne = 0;
53 #endif
54 
55 #ifdef MT_MODE
56 static T_MUTEX query_info_mutex;
57 #endif
58 
59 #ifdef MT_MODE
60 void
61 query_info_mutex_init ()
62 {
63  MUTEX_INIT (query_info_mutex);
64 }
65 #endif
66 
67 void
69 {
70  memset (qi, 0, sizeof (T_QUERY_INFO));
71  qi->min = 9999999;
72  qi->max = -1;
73 }
74 
75 void
77 {
78  FREE_MEM (qi->sql);
79  FREE_MEM (qi->organized_sql);
80  FREE_MEM (qi->cas_log);
81  qi->start_date[0] = '\0';
82 }
83 
84 void
86 {
87  int i;
88  char buf[1024];
89  FILE *fp_res, *fp_q;
90 #ifdef TEST
91  FILE *fp_tag, *fp_ne;
92 #endif
93  char minstr[64], maxstr[64], avgstr[64];
94  int xml_found;
95 
96 #ifdef MT_MODE
97  MUTEX_LOCK (query_info_mutex);
98 #endif
99 
100  fp_res = fopen (LOG_TOP_RES_FILE, "w");
101  fp_q = fopen (LOG_TOP_Q_FILE, "w");
102 #ifdef TEST
103  fp_tag = fopen (LOG_TOP_TAG_FILE, "w");
104  fp_ne = fopen (LOG_TOP_NE_FILE, "w");
105 #endif
106  if (fp_res == NULL || fp_q == NULL
107 #ifdef TEST
108  || fp_tag == NULL || fp_ne == NULL
109 #endif
110  )
111  {
112  fprintf (stderr, "%s\n", strerror (errno));
113  goto query_info_print_end;
114  }
115 
116  qsort (query_info_arr, num_query_info, sizeof (T_QUERY_INFO), sort_func);
117 
119  fprintf (fp_res, "%8s %8s %9s %9s %10s\n", "", "max", "min", "avg", "cnt(err)");
120  else
121  fprintf (fp_res, "%8s %8s %10s\n", "", "max", "cnt");
122 
123  fprintf (fp_res, "-----------------------------------------------------\n");
124 
125  for (i = 0; i < num_query_info; i++)
126  {
127  sprintf (buf, "[Q%d]", i + 1);
129  {
130  fprintf (fp_res, "%-8s %9s %9s %9s %4d (%d)", buf, time2str (query_info_arr[i].max, maxstr),
131  time2str (query_info_arr[i].min, minstr), time2str (query_info_arr[i].sum / query_info_arr[i].count,
132  avgstr), query_info_arr[i].count,
133  query_info_arr[i].err_count);
134  }
135  else
136  {
137  fprintf (fp_res, "%-8s %8d %10d", buf, query_info_arr[i].max, query_info_arr[i].count);
138  }
139 
140  fprintf (fp_q, "%s-------------------------------------------\n", buf);
141 
142  xml_found = sql_info_write (query_info_arr[i].sql, buf, fp_q);
143  if (xml_found)
144  {
145  fprintf (fp_res, "%5s", "X");
146  }
147 
148  fprintf (fp_res, "\n");
149 
150  fwrite (query_info_arr[i].cas_log, query_info_arr[i].cas_log_len, 1, fp_q);
151  fprintf (fp_q, "\n");
152 
153 #ifdef TEST
154  fprintf (fp_tag, "Q%d %s /^%s\n", i + 1, LOG_TOP_Q_FILE, buf);
155 #endif
156  }
157 
158 #ifdef TEST
159  for (i = 0; i < num_query_info_ne; i++)
160  {
161  sprintf (buf, "[N%d]", i + 1);
162  fprintf (fp_ne, "%s-------------------------------------------\n", buf);
163 
164  if (sql_info_write (query_info_arr_ne[i].sql, buf, fp_ne) < 0)
165  {
166  break;
167  }
168 
169  fprintf (fp_ne, "%s\n", query_info_arr_ne[i].cas_log);
170  }
171 #endif
172 
173  fclose (fp_res);
174  fclose (fp_q);
175 #ifdef TEST
176  fclose (fp_tag);
177  fclose (fp_ne);
178 #endif
179 
180 #ifdef TEST
181  sprintf (buf, "sort %s -o %s", LOG_TOP_TAG_FILE, LOG_TOP_TAG_FILE);
182  system (buf);
183 #endif
184 
185 query_info_print_end:
186 #ifdef MT_MODE
187  MUTEX_UNLOCK (query_info_mutex);
188 #endif
189  return;
190 }
191 
192 int
193 query_info_add (T_QUERY_INFO * qi, int exec_time, int execute_res, char *filename, int lineno, char *end_date)
194 {
195  int qi_idx = -1;
196  int i;
197  int retval;
198 
199  if (check_log_time (qi->start_date, end_date) < 0)
200  return 0;
201 
202 #ifdef MT_MODE
203  MUTEX_LOCK (query_info_mutex);
204 #endif
205 
206 #if 0
207  if (qi->sql == NULL)
208  goto query_info_add_end;
209 #endif
210 
211  for (i = 0; i < num_query_info; i++)
212  {
213  if (strcmp (query_info_arr[i].organized_sql, qi->organized_sql) == 0)
214  {
215  qi_idx = i;
216  break;
217  }
218  }
219 
220  if (qi_idx == -1)
221  {
222  query_info_arr = (T_QUERY_INFO *) REALLOC (query_info_arr, sizeof (T_QUERY_INFO) * (num_query_info + 1));
223  if (query_info_arr == NULL)
224  {
225  fprintf (stderr, "%s\n", strerror (errno));
226  retval = -1;
227  goto query_info_add_end;
228  }
229  qi_idx = num_query_info;
230  query_info_init (&query_info_arr[qi_idx]);
231  query_info_arr[qi_idx].sql = strdup (qi->sql);
232  query_info_arr[qi_idx].organized_sql = strdup (qi->organized_sql);
233  num_query_info++;
234  }
235 
236  if (exec_time < query_info_arr[qi_idx].min)
237  {
238  query_info_arr[qi_idx].min = exec_time;
239  }
240  if (exec_time > query_info_arr[qi_idx].max)
241  {
242  query_info_arr[qi_idx].max = exec_time;
243  FREE_MEM (query_info_arr[qi_idx].cas_log);
244  query_info_arr[qi_idx].cas_log = (char *) MALLOC (strlen (filename) + qi->cas_log_len + 20);
245  if (query_info_arr[qi_idx].cas_log == NULL)
246  {
247  fprintf (stderr, "%s\n", strerror (errno));
248  retval = -1;
249  goto query_info_add_end;
250  }
251  sprintf (query_info_arr[qi_idx].cas_log, "%s:%d\n", filename, lineno);
252  query_info_arr[qi_idx].cas_log_len = (int) strlen (query_info_arr[qi_idx].cas_log);
253  memcpy (query_info_arr[qi_idx].cas_log + query_info_arr[qi_idx].cas_log_len, qi->cas_log, qi->cas_log_len);
254  query_info_arr[qi_idx].cas_log_len += qi->cas_log_len;
255  }
256  query_info_arr[qi_idx].count++;
257  query_info_arr[qi_idx].sum += exec_time;
258  if (execute_res < 0)
259  {
260  query_info_arr[qi_idx].err_count++;
261  }
262  retval = 0;
263 
264 query_info_add_end:
265 
266 #ifdef MT_MODE
267  MUTEX_UNLOCK (query_info_mutex);
268 #endif
269  return retval;
270 }
271 
272 int
273 query_info_add_ne (T_QUERY_INFO * qi, char *end_date)
274 {
275 #ifndef TEST
276  /* query_info_arr_ne is used only in TEST mode */
277  return 0;
278 #else
279  int qi_idx = -1;
280  int i;
281  int retval;
282 
283  if (check_log_time (qi->start_date, end_date) < 0)
284  {
285  return 0;
286  }
287 
288 #ifdef MT_MODE
289  MUTEX_LOCK (query_info_mutex);
290 #endif
291 
292  for (i = 0; i < num_query_info; i++)
293  {
294  if (strcmp (query_info_arr[i].organized_sql, qi->organized_sql) == 0)
295  {
296  retval = 0;
297  goto query_info_add_ne_end;
298  }
299  }
300 
301  for (i = 0; i < num_query_info_ne; i++)
302  {
303  if (strcmp (query_info_arr_ne[i].organized_sql, qi->organized_sql) == 0)
304  {
305  qi_idx = i;
306  break;
307  }
308  }
309 
310  if (qi_idx == -1)
311  {
312  query_info_arr_ne = (T_QUERY_INFO *) REALLOC (query_info_arr_ne, sizeof (T_QUERY_INFO) * (num_query_info_ne + 1));
313  if (query_info_arr_ne == NULL)
314  {
315  fprintf (stderr, "%s\n", strerror (errno));
316  retval = -1;
317  goto query_info_add_ne_end;
318  }
319  qi_idx = num_query_info_ne;
320  query_info_init (&query_info_arr_ne[qi_idx]);
321  query_info_arr_ne[qi_idx].sql = strdup (qi->sql);
322  query_info_arr_ne[qi_idx].organized_sql = strdup (qi->organized_sql);
323  num_query_info_ne++;
324  }
325 
326  FREE_MEM (query_info_arr_ne[qi_idx].cas_log);
327  query_info_arr_ne[qi_idx].cas_log = strdup (qi->cas_log);
328  if (query_info_arr_ne[qi_idx].cas_log == NULL)
329  {
330  fprintf (stderr, "%s\n", strerror (errno));
331  retval = -1;
332  goto query_info_add_ne_end;
333  }
334 
335  retval = 0;
336 
337 query_info_add_ne_end:
338 #ifdef MT_MODE
339  MUTEX_UNLOCK (query_info_mutex);
340 #endif
341  return retval;
342 #endif /* define TEST */
343 }
344 
345 static int
346 sort_func (const void *arg1, const void *arg2)
347 {
348  return (((T_QUERY_INFO *) arg1)->max < ((T_QUERY_INFO *) arg2)->max);
349 }
350 
351 static char *
352 time2str (int t, char *buf)
353 {
354  int sec, msec;
355  sec = t / 1000;
356  msec = t % 1000;
357  if (sec >= 60)
358  sprintf (buf, "%d:%02d.%03d", sec / 60, sec % 60, msec);
359  else
360  sprintf (buf, "%d.%03d", sec, msec);
361 
362  return buf;
363 }
int sql_info_write(char *src_sql, char *q_name, FILE *fp)
T_LOG_TOP_MODE log_top_mode
int query_info_add(T_QUERY_INFO *qi, int exec_time, int execute_res, char *filename, int lineno, char *end_date)
void query_info_print(void)
#define LOG_TOP_TAG_FILE
#define LOG_TOP_NE_FILE
char * organized_sql
static T_QUERY_INFO * query_info_arr
#define LOG_TOP_Q_FILE
#define min(a, b)
char start_date[DATE_STR_LEN+1]
#define NULL
Definition: freelistheap.h:34
#define MALLOC(SIZE)
Definition: cas_common.h:53
#define FREE_MEM(PTR)
Definition: cas_common.h:58
void query_info_init(T_QUERY_INFO *qi)
int count(int &result, const cub_regex_object &reg, const std::string &src, const int position, const INTL_CODESET codeset)
#define LOG_TOP_RES_FILE
#define max(a, b)
void query_info_clear(T_QUERY_INFO *qi)
static char * time2str(int t, char *buf)
#define strlen(s1)
Definition: intl_support.c:43
int i
Definition: dynamic_load.c:954
int query_info_add_ne(T_QUERY_INFO *qi, char *end_date)
char * strdup(const char *str)
Definition: porting.c:901
static int sort_func(const void *arg1, const void *arg2)
int check_log_time(char *start_date, char *end_date)
#define REALLOC(PTR, SIZE)
Definition: cas_common.h:54
static int num_query_info