Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 96c4212

Browse files
committed
cvs add'd two files for the tprintf() patch...
1 parent f62d125 commit 96c4212

File tree

2 files changed

+435
-0
lines changed

2 files changed

+435
-0
lines changed

src/backend/utils/misc/trace.c

Lines changed: 350 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,350 @@
1+
/*-------------------------------------------------------------------------
2+
*
3+
* trace.c--
4+
*
5+
* Conditional trace ans logging functions.
6+
*
7+
* Massimo Dal Zotto <dz@cs.unitn.it>
8+
*
9+
*-------------------------------------------------------------------------
10+
*/
11+
12+
#include <stdio.h>
13+
#include <string.h>
14+
#include <time.h>
15+
#include <stdarg.h>
16+
#include <unistd.h>
17+
#include <signal.h>
18+
#include <sys/types.h>
19+
#include <sys/stat.h>
20+
#include <fcntl.h>
21+
22+
#ifdef USE_SYSLOG
23+
#include <syslog.h>
24+
#endif
25+
26+
#include "postgres.h"
27+
#include "miscadmin.h"
28+
#include "utils/trace.h"
29+
#include "libpq/pqsignal.h"
30+
31+
#ifdef USE_SYSLOG
32+
/*
33+
* Global option to control the use of syslog(3) for logging:
34+
*
35+
* 0 stdout/stderr only
36+
* 1 stdout/stderr + syslog
37+
* 2 syslog only
38+
*/
39+
#define UseSyslog pg_options[OPT_SYSLOG]
40+
#define PG_LOG_FACILITY LOG_LOCAL0
41+
#define PG_LOG_IDENT "postgres"
42+
#else
43+
#define UseSyslog 0
44+
#endif
45+
46+
/*
47+
* Trace option names, must match the constants in trace_opts[].
48+
*/
49+
static char *opt_names[] = {
50+
"all",
51+
"verbose",
52+
"query",
53+
"plan",
54+
"parse",
55+
"rewritten",
56+
"parserstats",
57+
"plannerstats",
58+
"executorstats",
59+
"shortlocks", /* currently unused but needed, see lock.c */
60+
"locks",
61+
"userlocks",
62+
"spinlocks",
63+
"notify",
64+
"malloc",
65+
"palloc",
66+
"lock_debug_oidmin",
67+
"lock_debug_relid",
68+
"lock_read_priority", /* lock priority, see lock.c */
69+
"deadlock_timeout", /* deadlock timeout, see proc.c */
70+
"syslog", /* use syslog for error messages */
71+
"hostlookup", /* enable hostname lookup in ps_status */
72+
"showportnumber", /* show port number in ps_status */
73+
"notifyunlock", /* enable unlock of pg_listener after notify */
74+
"notifyhack" /* enable notify hack to remove duplicate tuples */
75+
};
76+
77+
/*
78+
* Array of trace flags which can be set or reset independently.
79+
*/
80+
int pg_options[NUM_PG_OPTIONS] = { 0 };
81+
82+
static int openlog_done = 0;
83+
84+
/*
85+
* Print a timestamp and a message to stdout if the trace flag
86+
* indexed by the flag value is set.
87+
*/
88+
int
89+
tprintf(int flag, const char *fmt, ... )
90+
{
91+
va_list ap;
92+
char line[ELOG_MAXLEN+TIMESTAMP_SIZE+1];
93+
94+
#ifdef USE_SYSLOG
95+
int log_level;
96+
#endif
97+
98+
if ((flag == TRACE_ALL) || (pg_options[TRACE_ALL] > 0)) {
99+
/* uconditional trace or trace all option set */
100+
} else if (pg_options[TRACE_ALL] == 0) {
101+
if ((flag < 0) || (flag >= NUM_PG_OPTIONS) || (!pg_options[flag])) {
102+
return 0;
103+
}
104+
} else if (pg_options[TRACE_ALL] < 0) {
105+
return 0;
106+
}
107+
108+
va_start(ap, fmt);
109+
#ifdef ELOG_TIMESTAMPS
110+
strcpy(line, tprintf_timestamp());
111+
#endif
112+
vsprintf(line+TIMESTAMP_SIZE, fmt, ap);
113+
va_end(ap);
114+
115+
#ifdef USE_SYSLOG
116+
log_level = ((flag == TRACE_ALL) ? LOG_INFO : LOG_DEBUG);
117+
write_syslog(log_level, line+TIMESTAMP_SIZE);
118+
#endif
119+
120+
if (UseSyslog <= 1) {
121+
puts(line);
122+
fflush(stdout);
123+
}
124+
125+
return 1;
126+
}
127+
128+
/*
129+
* Print a timestamp and a message to stderr.
130+
*/
131+
int
132+
eprintf(const char *fmt, ... )
133+
{
134+
va_list ap;
135+
char line[ELOG_MAXLEN+TIMESTAMP_SIZE+1];
136+
137+
va_start(ap, fmt);
138+
#ifdef ELOG_TIMESTAMPS
139+
strcpy(line, tprintf_timestamp());
140+
#endif
141+
vsprintf(line+TIMESTAMP_SIZE, fmt, ap);
142+
va_end(ap);
143+
144+
#ifdef USE_SYSLOG
145+
write_syslog(LOG_ERR, line+TIMESTAMP_SIZE);
146+
#endif
147+
148+
if (UseSyslog <= 1) {
149+
fputs(line, stderr);
150+
fputc('\n', stderr);
151+
fflush(stderr);
152+
}
153+
154+
return 1;
155+
}
156+
157+
#ifdef USE_SYSLOG
158+
/*
159+
* Write a message line to syslog if the syslog option is set.
160+
*/
161+
void
162+
write_syslog(int level, char *line)
163+
{
164+
if (UseSyslog >= 1) {
165+
if (!openlog_done) {
166+
openlog_done = 1;
167+
openlog(PG_LOG_IDENT, LOG_PID|LOG_NDELAY, PG_LOG_FACILITY);
168+
}
169+
syslog(level, "%s", line);
170+
}
171+
}
172+
#endif
173+
174+
#ifdef ELOG_TIMESTAMPS
175+
/*
176+
* Return a timestamp string like "980119.17:25:59.902 [21974] "
177+
*/
178+
char *
179+
tprintf_timestamp()
180+
{
181+
struct timeval tv;
182+
struct tm *time;
183+
time_t tm;
184+
static char timestamp[32], pid[8];
185+
186+
gettimeofday(&tv, DST_NONE);
187+
tm = tv.tv_sec;
188+
time = localtime(&tm);
189+
190+
sprintf(pid, "[%d]", MyProcPid);
191+
sprintf(timestamp, "%02d%02d%02d.%02d:%02d:%02d.%03d %7s ",
192+
time->tm_year, time->tm_mon+1, time->tm_mday,
193+
time->tm_hour, time->tm_min, time->tm_sec,
194+
tv.tv_usec/1000, pid);
195+
196+
return timestamp;
197+
}
198+
#endif
199+
200+
int
201+
option_flag(int flag)
202+
{
203+
if ((flag < 0) || (flag >= NUM_PG_OPTIONS)) {
204+
return 0;
205+
}
206+
return pg_options[flag];
207+
}
208+
209+
int
210+
set_option_flag(int flag, int value)
211+
{
212+
if ((flag < 0) || (flag >= NUM_PG_OPTIONS)) {
213+
return -1;
214+
}
215+
216+
pg_options[flag] = value;
217+
return value;
218+
}
219+
220+
/*
221+
* Parse an option string like "name,name+,name-,name=value".
222+
* Single options are delimited by ',',space,tab,newline or cr.
223+
*/
224+
void
225+
parse_options(char *str)
226+
{
227+
char *s,
228+
*name;
229+
int i,
230+
len,
231+
val,
232+
is_comment;
233+
234+
Assert((sizeof(opt_names)/sizeof(char*)) == NUM_PG_OPTIONS);
235+
236+
str = strdup(str);
237+
for (s=str; *s;) {
238+
is_comment = 0;
239+
name = s;
240+
val = 1;
241+
for (; *s; s++) {
242+
switch (*s) {
243+
case '#':
244+
is_comment = 1;
245+
break;
246+
case '=':
247+
*s++ = '\0';
248+
val = strtol(s, &s, 10);
249+
goto setval;
250+
case '-':
251+
*s++ = '\0';
252+
val = 0;
253+
goto setval;
254+
case '+':
255+
*s++ = '\0';
256+
val = 1;
257+
goto setval;
258+
case ' ':
259+
case ',':
260+
case '\t':
261+
case '\n':
262+
case '\r':
263+
*s = ',';
264+
val = 1;
265+
goto setval;
266+
}
267+
}
268+
setval:
269+
for (; *s; s++) {
270+
if (*s == ',') {
271+
*s++ = '\0';
272+
break;
273+
}
274+
}
275+
len = strlen(name);
276+
if (len == 0) {
277+
continue;
278+
}
279+
for (i=0; i<NUM_PG_OPTIONS; i++) {
280+
if (strncmp(name, opt_names[i], len) == 0) {
281+
pg_options[i] = val;
282+
break;
283+
}
284+
}
285+
if (!is_comment && (i >= NUM_PG_OPTIONS)) {
286+
fprintf(stderr, "invalid option: %s\n", name);
287+
}
288+
}
289+
free(str);
290+
}
291+
292+
#define BUF_SIZE 4096
293+
294+
void
295+
read_pg_options(SIGNAL_ARGS)
296+
{
297+
int fd;
298+
int n;
299+
int verbose;
300+
char buffer[BUF_SIZE];
301+
char c;
302+
char *s,
303+
*p;
304+
305+
sprintf(buffer, "%s/%s", DataDir, "pg_options");
306+
if ((fd = open(buffer, O_RDONLY)) < 0) {
307+
return;
308+
}
309+
310+
if ((n = read(fd, buffer, BUF_SIZE-1)) > 0) {
311+
/* collpse buffer in place removing comments and spaces */
312+
for (s=buffer,p=buffer,c='\0'; s<(buffer+n); ) {
313+
switch (*s) {
314+
case '#':
315+
while ((s < (buffer+n)) && (*s++ != '\n'));
316+
break;
317+
case ' ':
318+
case '\t':
319+
case '\n':
320+
case '\r':
321+
if (c != ',')
322+
c = *p++ = ',';
323+
s++;
324+
break;
325+
default:
326+
c = *p++ = *s++;
327+
break;
328+
}
329+
}
330+
if (c == ',')
331+
p--;
332+
*p = '\0';
333+
verbose = pg_options[TRACE_VERBOSE];
334+
parse_options(buffer);
335+
verbose |= pg_options[TRACE_VERBOSE];
336+
if (verbose || postgres_signal_arg == SIGHUP) {
337+
tprintf(TRACE_ALL, "read_pg_options: %s", buffer);
338+
}
339+
}
340+
341+
close(fd);
342+
}
343+
344+
/*
345+
* Local variables:
346+
* tab-width: 4
347+
* c-indent-level: 4
348+
* c-basic-offset: 4
349+
* End:
350+
*/

0 commit comments

Comments
 (0)