PostgreSQL Source Code: src/backend/utils/error/elog.c Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
56
57#include <fcntl.h>
60#include <signal.h>
61#include <ctype.h>
62#ifdef HAVE_SYSLOG
63#include <syslog.h>
64#endif
65#ifdef HAVE_EXECINFO_H
66#include <execinfo.h>
67#endif
68
87
88
89
90#undef _
91#define _(x) err_gettext(x)
92
93
94
96
98
99
100
101
102
103
104
105
107
108
115
116
118
119#ifdef HAVE_SYSLOG
120
121
122
123
124
125
126
127
128#ifndef PG_SYSLOG_LIMIT
129#define PG_SYSLOG_LIMIT 900
130#endif
131
132static bool openlog_done = false;
133static char *syslog_ident = NULL;
135
136static void write_syslog(int level, const char *line);
137#endif
138
139#ifdef WIN32
140static void write_eventlog(int level, const char *line, int len);
141#endif
142
143
144#define ERRORDATA_STACK_SIZE 5
145
147
149
151
152
153
154
155
158
159#define FORMATTED_TS_LEN 128
162
163
164
165#define CHECK_STACK_DEPTH() \
166 do { \
167 if (errordata_stack_depth < 0) \
168 { \
169 errordata_stack_depth = -1; \
170 ereport(ERROR, (errmsg_internal("errstart was not called"))); \
171 } \
172 } while (0)
173
174
179 const char *filename, int lineno,
191
192
193
194
195
196
197
198
199
200
201static inline bool
203{
205 {
206 if (log_min_level == LOG || log_min_level <= ERROR)
207 return true;
208 }
210 {
211
212 return false;
213 }
214 else if (log_min_level == LOG)
215 {
216
217 if (elevel >= FATAL)
218 return true;
219 }
220
221 else if (elevel >= log_min_level)
222 return true;
223
224 return false;
225}
226
227
228
229
230
231
232
233
234
235static inline bool
237{
239}
240
241
242
243
244static inline bool
246{
248 {
249
250
251
252
253
254
256 return (elevel >= ERROR);
257 else
259 }
260 return false;
261}
262
263
264
265
266
267
268
269
270
271
272bool
274{
275
276
277
278 if (elevel >= ERROR ||
281 return true;
282 return false;
283}
284
285
286
287
288
289
290
291
292
293bool
295{
296
298}
299
300
301
302
303
304
305static inline const char *
307{
308#ifdef ENABLE_NLS
310 return str;
311 else
313#else
314 return str;
315#endif
316}
317
318
319
320
321
322
323
324
325
328{
329 return errstart(elevel, domain);
330}
331
332
333
334
335
336
337
338
339
340
341
342bool
344{
346 bool output_to_server;
347 bool output_to_client = false;
348 int i;
349
350
351
352
353
354 if (elevel >= ERROR)
355 {
356
357
358
359
362
363
364
365
366
367
368
369
370
371
372
373
374
375 if (elevel == ERROR)
376 {
381 }
382
383
384
385
386
387
388
389
390
393 }
394
395
396
397
398
399
402 if (elevel < ERROR && !output_to_server && !output_to_client)
403 return false;
404
405
406
407
408
410 {
411
412 write_stderr("error occurred before error message processing is available\n");
413 exit(2);
414 }
415
416
417
418
419
421 {
422
423
424
425
426
428
429
430
431
432
433
434
436 {
439 }
440 }
441
442
444 edata->elevel = elevel;
448
449 if (elevel >= ERROR)
450 edata->sqlerrcode = ERRCODE_INTERNAL_ERROR;
451 else if (elevel >= WARNING)
453 else
454 edata->sqlerrcode = ERRCODE_SUCCESSFUL_COMPLETION;
455
456
457
458
460
462 return true;
463}
464
465
466
467
468
469
470
471
472
473void
475{
477 int elevel;
480
483
484
486
487 elevel = edata->elevel;
488
489
490
491
492
494
495
501
502
503
504
505
506
508 econtext != NULL;
509 econtext = econtext->previous)
511
512
513
514
515
516 if (elevel == ERROR)
517 {
518
519
520
521
522
523
524
525
526
527
530
532
533
534
535
536
537
540 }
541
542
544
545
548
549
552
553
554
555
556 if (elevel == FATAL)
557 {
558
559
560
561
562
563
566
567
568
569
570
571
572
573 fflush(NULL);
574
575
576
577
578
581
582
583
584
585
586
588 }
589
590 if (elevel >= PANIC)
591 {
592
593
594
595
596
597
598
599 fflush(NULL);
600 abort();
601 }
602
603
604
605
606
607
609}
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629bool
631{
634
635
636
637
638
641
642
645
646
648 return false;
649
650
651
652
653
655
656
660
661 edata->sqlerrcode = ERRCODE_INTERNAL_ERROR;
662
663
664
665
666
667
669
671 return true;
672}
673
674
675
676
677
678
679
680
681void
684{
687
688
690
691
692
693
694
696 {
699 }
700
701
702
703
704
706
707
709
710
712
713
714
715
716
717
718
719
720
721
722
723
726
727
730}
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
753{
755
756
759 {
760
763 }
764
765
767 memset(edata, 0, sizeof(ErrorData));
768
769
771
772 return edata;
773}
774
775
776
777
778static void
780{
781
783
785}
786
787
788
789
790
791
792
793
794
795static void
797 const char *filename, int lineno,
799{
801 {
802 const char *slash;
803
804
805 slash = strrchr(filename, '/');
806 if (slash)
808
809 slash = strrchr(filename, '\\');
810 if (slash)
812 }
813
815 edata->lineno = lineno;
817}
818
819
820
821
822
823
824
825static bool
827{
828 const char *p;
829
831 return false;
832
834 for (;;)
835 {
836 if (*p == '\0')
837 break;
838
839 if (strcmp(funcname, p) == 0)
840 return true;
841 p += strlen(p) + 1;
842 }
843
844 return false;
845}
846
847
848
849
850
851
852
853int
855{
857
858
860
862
863 return 0;
864}
865
866
867
868
869
870
871
872
873
874
875
876int
878{
880
881
883
885 {
886
887 case EPERM:
888 case EACCES:
889#ifdef EROFS
890 case EROFS:
891#endif
892 edata->sqlerrcode = ERRCODE_INSUFFICIENT_PRIVILEGE;
893 break;
894
895
896 case ENOENT:
897 edata->sqlerrcode = ERRCODE_UNDEFINED_FILE;
898 break;
899
900
901 case EEXIST:
902 edata->sqlerrcode = ERRCODE_DUPLICATE_FILE;
903 break;
904
905
906 case ENOTDIR:
907 case EISDIR:
908 case ENOTEMPTY:
909 edata->sqlerrcode = ERRCODE_WRONG_OBJECT_TYPE;
910 break;
911
912
913 case ENOSPC:
914 edata->sqlerrcode = ERRCODE_DISK_FULL;
915 break;
916
917 case ENOMEM:
918 edata->sqlerrcode = ERRCODE_OUT_OF_MEMORY;
919 break;
920
921 case ENFILE:
922 case EMFILE:
923 edata->sqlerrcode = ERRCODE_INSUFFICIENT_RESOURCES;
924 break;
925
926
927 case EIO:
928 edata->sqlerrcode = ERRCODE_IO_ERROR;
929 break;
930
931 case ENAMETOOLONG:
932 edata->sqlerrcode = ERRCODE_FILE_NAME_TOO_LONG;
933 break;
934
935
936 default:
937 edata->sqlerrcode = ERRCODE_INTERNAL_ERROR;
938 break;
939 }
940
941 return 0;
942}
943
944
945
946
947
948
949
950
951
952
953int
955{
957
958
960
962 {
963
965 edata->sqlerrcode = ERRCODE_CONNECTION_FAILURE;
966 break;
967
968
969 default:
970 edata->sqlerrcode = ERRCODE_INTERNAL_ERROR;
971 break;
972 }
973
974 return 0;
975}
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990#define EVALUATE_MESSAGE(domain, targetfield, appendval, translateit) \
991 { \
992 StringInfoData buf; \
993 \
994 if ((translateit) && !in_error_recursion_trouble()) \
995 fmt = dgettext((domain), fmt); \
996 initStringInfo(&buf); \
997 if ((appendval) && edata->targetfield) { \
998 appendStringInfoString(&buf, edata->targetfield); \
999 appendStringInfoChar(&buf, '\n'); \
1000 } \
1001 \
1002 for (;;) \
1003 { \
1004 va_list args; \
1005 int needed; \
1006 errno = edata->saved_errno; \
1007 va_start(args, fmt); \
1008 needed = appendStringInfoVA(&buf, fmt, args); \
1009 va_end(args); \
1010 if (needed == 0) \
1011 break; \
1012 enlargeStringInfo(&buf, needed); \
1013 } \
1014 \
1015 if (edata->targetfield) \
1016 pfree(edata->targetfield); \
1017 edata->targetfield = pstrdup(buf.data); \
1018 pfree(buf.data); \
1019 }
1020
1021
1022
1023
1024
1025
1026#define EVALUATE_MESSAGE_PLURAL(domain, targetfield, appendval) \
1027 { \
1028 const char *fmt; \
1029 StringInfoData buf; \
1030 \
1031 if (!in_error_recursion_trouble()) \
1032 fmt = dngettext((domain), fmt_singular, fmt_plural, n); \
1033 else \
1034 fmt = (n == 1 ? fmt_singular : fmt_plural); \
1035 initStringInfo(&buf); \
1036 if ((appendval) && edata->targetfield) { \
1037 appendStringInfoString(&buf, edata->targetfield); \
1038 appendStringInfoChar(&buf, '\n'); \
1039 } \
1040 \
1041 for (;;) \
1042 { \
1043 va_list args; \
1044 int needed; \
1045 errno = edata->saved_errno; \
1046 va_start(args, n); \
1047 needed = appendStringInfoVA(&buf, fmt, args); \
1048 va_end(args); \
1049 if (needed == 0) \
1050 break; \
1051 enlargeStringInfo(&buf, needed); \
1052 } \
1053 \
1054 if (edata->targetfield) \
1055 pfree(edata->targetfield); \
1056 edata->targetfield = pstrdup(buf.data); \
1057 pfree(buf.data); \
1058 }
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070int
1072{
1075
1079
1082
1085 return 0;
1086}
1087
1088
1089
1090
1091
1092int
1094{
1097
1101
1103
1106
1107 return 0;
1108}
1109
1110
1111
1112
1113
1114
1115
1116static void
1118{
1120
1122
1123#ifdef HAVE_BACKTRACE_SYMBOLS
1124 {
1125 void *buf[100];
1126 int nframes;
1127 char **strfrms;
1128
1130 strfrms = backtrace_symbols(buf, nframes);
1131 if (strfrms == NULL)
1132 return;
1133
1134 for (int i = num_skip; i < nframes; i++)
1136 free(strfrms);
1137 }
1138#else
1140 "backtrace generation is not supported by this installation");
1141#endif
1142
1144}
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157int
1159{
1162
1166
1169
1172 return 0;
1173}
1174
1175
1176
1177
1178
1179
1180int
1182 unsigned long n,...)
1183{
1186
1190
1193
1196 return 0;
1197}
1198
1199
1200
1201
1202
1203int
1205{
1208
1212
1214
1217 return 0;
1218}
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230int
1232{
1235
1239
1241
1244 return 0;
1245}
1246
1247
1248
1249
1250
1251int
1253{
1256
1260
1262
1265 return 0;
1266}
1267
1268
1269
1270
1271
1272int
1274 unsigned long n,...)
1275{
1278
1282
1284
1287 return 0;
1288}
1289
1290
1291
1292
1293
1294
1295int
1297 unsigned long n,...)
1298{
1301
1305
1307
1310 return 0;
1311}
1312
1313
1314
1315
1316
1317int
1319{
1322
1326
1328
1331 return 0;
1332}
1333
1334
1335
1336
1337
1338
1339int
1341{
1344
1348
1350
1353 return 0;
1354}
1355
1356
1357
1358
1359
1360int
1362 unsigned long n,...)
1363{
1366
1370
1372
1375 return 0;
1376}
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386int
1388{
1391
1395
1397
1400 return 0;
1401}
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412int
1414{
1416
1417
1419
1420
1422
1423 return 0;
1424}
1425
1426
1427
1428
1429
1430
1431
1432int
1434{
1436
1437
1439
1441
1442 return 0;
1443}
1444
1445
1446
1447
1448
1449
1450
1451int
1453{
1455
1456
1458
1460
1461 return 0;
1462}
1463
1464
1465
1466
1467int
1469{
1471
1472
1474
1476
1477 return 0;
1478}
1479
1480
1481
1482
1483int
1485{
1487
1488
1490
1492
1493 return 0;
1494}
1495
1496
1497
1498
1499
1500
1501
1502
1503int
1505{
1507
1508
1510
1512 {
1515 }
1516
1517 if (query)
1519
1520 return 0;
1521}
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533int
1535{
1537
1538
1540
1541 switch (field)
1542 {
1545 break;
1548 break;
1551 break;
1554 break;
1557 break;
1558 default:
1559 elog(ERROR, "unsupported ErrorData field id: %d", field);
1560 break;
1561 }
1562
1563 return 0;
1564}
1565
1566
1567
1568
1569static void
1571{
1572 Assert(*ptr == NULL);
1574}
1575
1576
1577
1578
1579
1580
1581
1582int
1584{
1586
1587
1589
1591}
1592
1593
1594
1595
1596
1597
1598
1599int
1601{
1603
1604
1606
1608}
1609
1610
1611
1612
1613
1614
1615
1616int
1618{
1620
1621
1623
1625}
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1648
1649void
1651{
1652
1654
1656}
1657
1658char *
1660{
1664
1665
1666 edata = &errdata;
1668
1670
1672
1674
1677
1679
1681}
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691void
1693{
1696
1700
1701
1702
1703
1704
1705
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1729 (*emit_log_hook) (edata);
1730
1731
1734
1735
1738
1741}
1742
1743
1744
1745
1746
1747
1748
1749
1752{
1755
1756
1757
1758
1759
1761
1763
1764
1766 memcpy(newedata, edata, sizeof(ErrorData));
1767
1768
1769
1770
1771
1772
1773
1774
1779 if (newedata->domain)
1785 if (newedata->detail)
1789 if (newedata->hint)
1809
1810
1812
1813 return newedata;
1814}
1815
1816
1817
1818
1819
1820
1821
1822void
1824{
1827}
1828
1829
1830
1831
1832
1833
1834static void
1836{
1843 if (edata->hint)
1861}
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871void
1873{
1874
1875
1876
1877
1878
1879
1882
1884}
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899void
1901{
1904
1906 return;
1907
1911
1912
1921 if (edata->hint)
1927
1942
1945
1946
1948}
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958void
1960{
1962
1964
1965
1968
1970 memcpy(newedata, edata, sizeof(ErrorData));
1971
1972
1975 if (newedata->detail)
1979 if (newedata->hint)
1997
1998
2000
2003}
2004
2005
2006
2007
2008void
2010{
2011
2014 else
2015 {
2016
2017
2018
2019
2020
2021
2022
2023
2025
2029
2030
2031
2032
2033
2036
2037
2038
2039
2040
2041
2043
2045 }
2046
2047
2049}
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063char *
2065{
2068
2069
2070
2071
2073
2075
2076
2077
2078
2079
2081
2082
2083
2084
2085
2086
2087
2088
2089
2091 econtext != NULL;
2092 econtext = econtext->previous)
2094
2095
2096
2097
2098
2099
2100
2103
2104
2105
2106
2107
2109}
2110
2111
2112
2113
2114
2115void
2117{
2118 int fd,
2119 istty;
2120
2122 {
2123
2124
2125
2126
2127
2128 if ((fd = open(OutputFileName, O_CREAT | O_APPEND | O_WRONLY,
2129 0666)) < 0)
2133 istty = isatty(fd);
2135
2136
2137
2138
2142 errmsg("could not reopen file \"%s\" as stderr: %m",
2144
2145
2146
2147
2148
2149
2150
2155 errmsg("could not reopen file \"%s\" as stdout: %m",
2157 }
2158}
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171bool
2173{
2174 int newvallen = strlen(*newval);
2175 char *someval;
2176 int validlen;
2177 int i;
2178 int j;
2179
2180
2181
2182
2183
2184 validlen = strspn(*newval,
2185 "0123456789_"
2186 "abcdefghijklmnopqrstuvwxyz"
2187 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
2188 ", \n\t");
2189 if (validlen != newvallen)
2190 {
2192 return false;
2193 }
2194
2195 if (*newval[0] == '\0')
2196 {
2197 *extra = NULL;
2198 return true;
2199 }
2200
2201
2202
2203
2204
2205
2207 if (!someval)
2208 return false;
2209 for (i = 0, j = 0; i < newvallen; i++)
2210 {
2212 someval[j++] = '\0';
2213 else if ((*newval)[i] == ' ' ||
2216 ;
2217 else
2218 someval[j++] = (*newval)[i];
2219 }
2220
2221
2222 someval[j] = '\0';
2223 someval[j + 1] = '\0';
2224
2225 *extra = someval;
2226 return true;
2227}
2228
2229
2230
2231
2232void
2234{
2236}
2237
2238
2239
2240
2241bool
2243{
2244 char *rawstring;
2245 List *elemlist;
2247 int newlogdest = 0;
2248 int *myextra;
2249
2250
2252
2253
2255 {
2256
2258 pfree(rawstring);
2260 return false;
2261 }
2262
2263 foreach(l, elemlist)
2264 {
2265 char *tok = (char *) lfirst(l);
2266
2273#ifdef HAVE_SYSLOG
2276#endif
2277#ifdef WIN32
2280#endif
2281 else
2282 {
2284 pfree(rawstring);
2286 return false;
2287 }
2288 }
2289
2290 pfree(rawstring);
2292
2294 if (!myextra)
2295 return false;
2296 *myextra = newlogdest;
2297 *extra = myextra;
2298
2299 return true;
2300}
2301
2302
2303
2304
2305void
2307{
2309}
2310
2311
2312
2313
2314void
2316{
2317#ifdef HAVE_SYSLOG
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328 if (syslog_ident == NULL || strcmp(syslog_ident, newval) != 0)
2329 {
2330 if (openlog_done)
2331 {
2332 closelog();
2333 openlog_done = false;
2334 }
2335 free(syslog_ident);
2336 syslog_ident = strdup(newval);
2337
2338 }
2339#endif
2340
2341}
2342
2343
2344
2345
2346void
2348{
2349#ifdef HAVE_SYSLOG
2350
2351
2352
2354 {
2355 if (openlog_done)
2356 {
2357 closelog();
2358 openlog_done = false;
2359 }
2361 }
2362#endif
2363
2364}
2365
2366#ifdef HAVE_SYSLOG
2367
2368
2369
2370
2371static void
2372write_syslog(int level, const char *line)
2373{
2374 static unsigned long seq = 0;
2375
2376 int len;
2377 const char *nlpos;
2378
2379
2380 if (!openlog_done)
2381 {
2382 openlog(syslog_ident ? syslog_ident : "postgres",
2383 LOG_PID | LOG_NDELAY | LOG_NOWAIT,
2385 openlog_done = true;
2386 }
2387
2388
2389
2390
2391
2392 seq++;
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402 len = strlen(line);
2403 nlpos = strchr(line, '\n');
2405 {
2406 int chunk_nr = 0;
2407
2408 while (len > 0)
2409 {
2410 char buf[PG_SYSLOG_LIMIT + 1];
2411 int buflen;
2412 int i;
2413
2414
2415 if (line[0] == '\n')
2416 {
2417 line++;
2419
2420 nlpos = strchr(line, '\n');
2421 continue;
2422 }
2423
2424
2425 if (nlpos != NULL)
2426 buflen = nlpos - line;
2427 else
2428 buflen = len;
2429 buflen = Min(buflen, PG_SYSLOG_LIMIT);
2430 memcpy(buf, line, buflen);
2431 buf[buflen] = '\0';
2432
2433
2435 if (buflen <= 0)
2436 return;
2437 buf[buflen] = '\0';
2438
2439
2440 if (line[buflen] != '\0' &&
2441 !isspace((unsigned char) line[buflen]))
2442 {
2443
2444 i = buflen - 1;
2445 while (i > 0 && !isspace((unsigned char) buf[i]))
2446 i--;
2447
2448 if (i > 0)
2449 {
2450 buflen = i;
2452 }
2453 }
2454
2455 chunk_nr++;
2456
2458 syslog(level, "[%lu-%d] %s", seq, chunk_nr, buf);
2459 else
2460 syslog(level, "[%d] %s", chunk_nr, buf);
2461
2462 line += buflen;
2463 len -= buflen;
2464 }
2465 }
2466 else
2467 {
2468
2470 syslog(level, "[%lu] %s", seq, line);
2471 else
2472 syslog(level, "%s", line);
2473 }
2474}
2475#endif
2476
2477#ifdef WIN32
2478
2479
2480
2481
2482
2483static int
2484GetACPEncoding(void)
2485{
2487
2489 encoding = pg_codepage_to_encoding(GetACP());
2490
2492}
2493
2494
2495
2496
2497static void
2498write_eventlog(int level, const char *line, int len)
2499{
2500 WCHAR *utf16;
2501 int eventlevel = EVENTLOG_ERROR_TYPE;
2502 static HANDLE evtHandle = INVALID_HANDLE_VALUE;
2503
2504 if (evtHandle == INVALID_HANDLE_VALUE)
2505 {
2506 evtHandle = RegisterEventSource(NULL,
2508 if (evtHandle == NULL)
2509 {
2510 evtHandle = INVALID_HANDLE_VALUE;
2511 return;
2512 }
2513 }
2514
2515 switch (level)
2516 {
2522 case LOG:
2526 eventlevel = EVENTLOG_INFORMATION_TYPE;
2527 break;
2530 eventlevel = EVENTLOG_WARNING_TYPE;
2531 break;
2535 default:
2536 eventlevel = EVENTLOG_ERROR_TYPE;
2537 break;
2538 }
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2556 {
2557 utf16 = pgwin32_message_to_UTF16(line, len, NULL);
2558 if (utf16)
2559 {
2560 ReportEventW(evtHandle,
2561 eventlevel,
2562 0,
2563 0,
2564 NULL,
2565 1,
2566 0,
2567 (LPCWSTR *) &utf16,
2568 NULL);
2569
2570
2572 return;
2573 }
2574 }
2575 ReportEventA(evtHandle,
2576 eventlevel,
2577 0,
2578 0,
2579 NULL,
2580 1,
2581 0,
2582 &line,
2583 NULL);
2584}
2585#endif
2586
2587static void
2589{
2590 int rc;
2591
2592#ifdef WIN32
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2614 {
2615 WCHAR *utf16;
2616 int utf16len;
2617
2618 utf16 = pgwin32_message_to_UTF16(line, len, &utf16len);
2619 if (utf16 != NULL)
2620 {
2621 HANDLE stdHandle;
2622 DWORD written;
2623
2624 stdHandle = GetStdHandle(STD_ERROR_HANDLE);
2625 if (WriteConsoleW(stdHandle, utf16, utf16len, &written, NULL))
2626 {
2628 return;
2629 }
2630
2631
2632
2633
2634
2636 }
2637 }
2638#else
2639
2640
2641
2642
2643
2644
2645
2646
2647#endif
2648
2649
2650
2651
2652
2653 rc = write(fileno(stderr), line, len);
2654 (void) rc;
2655}
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665char *
2667{
2669 char msbuf[13];
2670
2671
2674
2676 {
2679 }
2680
2682
2683
2684
2685
2686
2687
2689
2690 "%Y-%m-%d %H:%M:%S %Z",
2692
2693
2696
2698}
2699
2700
2701
2702
2703void
2705{
2707}
2708
2709
2710
2711
2712
2713
2714
2715char *
2717{
2719
2720
2723
2724
2725
2726
2727
2728
2730 "%Y-%m-%d %H:%M:%S %Z",
2732
2734}
2735
2736
2737
2738
2739bool
2741{
2742
2744 return false;
2745
2746
2748 return false;
2749
2750
2752 return false;
2753
2754 return true;
2755}
2756
2757
2758
2759
2760
2761
2762const char *
2764{
2765 const char *backend_type_str;
2766
2768 backend_type_str = "postmaster";
2771 else
2773
2774 return backend_type_str;
2775}
2776
2777
2778
2779
2780
2781
2782
2783
2784static const char *
2786{
2787 int paddingsign = 1;
2788 int padding = 0;
2789
2790 if (*p == '-')
2791 {
2792 p++;
2793
2794 if (*p == '\0')
2795 return NULL;
2796 paddingsign = -1;
2797 }
2798
2799
2800 while (*p >= '0' && *p <= '9')
2801 padding = padding * 10 + (*p++ - '0');
2802
2803
2804 if (*p == '\0')
2805 return NULL;
2806
2807 padding *= paddingsign;
2808 *ppadding = padding;
2809 return p;
2810}
2811
2812
2813
2814
2815static void
2817{
2819}
2820
2821
2822
2823
2824void
2826{
2827
2828 static long log_line_number = 0;
2829
2830
2831 static int log_my_pid = 0;
2832 int padding;
2833 const char *p;
2834
2835
2836
2837
2838
2839
2840
2842 {
2843 log_line_number = 0;
2846 }
2847 log_line_number++;
2848
2850 return;
2851
2852 for (p = format; *p != '\0'; p++)
2853 {
2854 if (*p != '%')
2855 {
2856
2858 continue;
2859 }
2860
2861
2862 p++;
2863 if (*p == '\0')
2864 break;
2865 else if (*p == '%')
2866 {
2867
2869 continue;
2870 }
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887 if (*p > '9')
2888 padding = 0;
2890 break;
2891
2892
2893 switch (*p)
2894 {
2895 case 'a':
2897 {
2899
2900 if (appname == NULL || *appname == '\0')
2901 appname = _("[unknown]");
2902 if (padding != 0)
2904 else
2906 }
2907 else if (padding != 0)
2909 padding > 0 ? padding : -padding);
2910
2911 break;
2912 case 'b':
2913 {
2915
2916 if (padding != 0)
2918 else
2920 break;
2921 }
2922 case 'u':
2924 {
2926
2929 if (padding != 0)
2931 else
2933 }
2934 else if (padding != 0)
2936 padding > 0 ? padding : -padding);
2937 break;
2938 case 'd':
2940 {
2942
2945 if (padding != 0)
2947 else
2949 }
2950 else if (padding != 0)
2952 padding > 0 ? padding : -padding);
2953 break;
2954 case 'c':
2955 if (padding != 0)
2956 {
2957 char strfbuf[128];
2958
2962 }
2963 else
2965 break;
2966 case 'p':
2967 if (padding != 0)
2969 else
2971 break;
2972
2973 case 'P':
2975 {
2977
2978
2979
2980
2981
2982 if (leader == NULL || leader->pid == MyProcPid)
2984 padding > 0 ? padding : -padding);
2985 else if (padding != 0)
2987 else
2989 }
2990 else if (padding != 0)
2992 padding > 0 ? padding : -padding);
2993 break;
2994
2995 case 'l':
2996 if (padding != 0)
2998 else
3000 break;
3001 case 'm':
3002
3005
3006 if (padding != 0)
3008 else
3010 break;
3011 case 't':
3012 {
3014 char strfbuf[128];
3015
3017 "%Y-%m-%d %H:%M:%S %Z",
3019 if (padding != 0)
3021 else
3023 }
3024 break;
3025 case 'n':
3026 {
3027 char strfbuf[128];
3028
3030 {
3033 }
3034
3035 snprintf(strfbuf, sizeof(strfbuf), "%ld.%03d",
3038
3039 if (padding != 0)
3041 else
3043 }
3044 break;
3045 case 's':
3046 {
3048
3049 if (padding != 0)
3051 else
3053 }
3054 break;
3055 case 'i':
3057 {
3058 const char *psdisp;
3059 int displen;
3060
3062 if (padding != 0)
3064 else
3066 }
3067 else if (padding != 0)
3069 padding > 0 ? padding : -padding);
3070 break;
3071 case 'L':
3072 {
3073 const char *local_host;
3074
3076 {
3078 {
3079
3080
3081
3082
3087 NULL, 0,
3088 NI_NUMERICHOST | NI_NUMERICSERV);
3089 }
3091 }
3092 else
3093 {
3094
3095 local_host = "[none]";
3096 }
3097 if (padding != 0)
3099 else
3101 }
3102 break;
3103 case 'r':
3105 {
3106 if (padding != 0)
3107 {
3109 {
3110
3111
3112
3113
3114
3115
3116
3117
3118 char *hostport;
3119
3122 pfree(hostport);
3123 }
3124 else
3126 }
3127 else
3128 {
3129
3135 }
3136 }
3137 else if (padding != 0)
3139 padding > 0 ? padding : -padding);
3140 break;
3141 case 'h':
3143 {
3144 if (padding != 0)
3146 else
3148 }
3149 else if (padding != 0)
3151 padding > 0 ? padding : -padding);
3152 break;
3153 case 'q':
3154
3155
3157 return;
3158 break;
3159 case 'v':
3160
3162 {
3163 if (padding != 0)
3164 {
3165 char strfbuf[128];
3166
3167 snprintf(strfbuf, sizeof(strfbuf) - 1, "%d/%u",
3170 }
3171 else
3173 }
3174 else if (padding != 0)
3176 padding > 0 ? padding : -padding);
3177 break;
3178 case 'x':
3179 if (padding != 0)
3181 else
3183 break;
3184 case 'e':
3185 if (padding != 0)
3187 else
3189 break;
3190 case 'Q':
3191 if (padding != 0)
3194 else
3197 break;
3198 default:
3199
3200 break;
3201 }
3202 }
3203}
3204
3205
3206
3207
3208
3209char *
3211{
3212 static char buf[12];
3213 int i;
3214
3216 {
3218 sql_state >>= 6;
3219 }
3220
3222 return buf;
3223}
3224
3225
3226
3227
3228
3229static void
3231{
3233 bool fallback_to_stderr = false;
3234
3236
3239
3242
3245 else
3247
3254
3256
3258 {
3260 {
3265 }
3266 else if (edata->detail)
3267 {
3272 }
3273 if (edata->hint)
3274 {
3279 }
3281 {
3286 }
3288 {
3293 }
3295 {
3296
3298 {
3303 }
3305 {
3309 }
3310 }
3312 {
3317 }
3318 }
3319
3320
3321
3322
3324 {
3329 }
3330
3331#ifdef HAVE_SYSLOG
3332
3334 {
3335 int syslog_level;
3336
3337 switch (edata->elevel)
3338 {
3344 syslog_level = LOG_DEBUG;
3345 break;
3346 case LOG:
3349 syslog_level = LOG_INFO;
3350 break;
3354 syslog_level = LOG_NOTICE;
3355 break;
3357 syslog_level = LOG_WARNING;
3358 break;
3360 syslog_level = LOG_ERR;
3361 break;
3363 default:
3364 syslog_level = LOG_CRIT;
3365 break;
3366 }
3367
3368 write_syslog(syslog_level, buf.data);
3369 }
3370#endif
3371
3372#ifdef WIN32
3373
3375 {
3376 write_eventlog(edata->elevel, buf.data, buf.len);
3377 }
3378#endif
3379
3380
3382 {
3383
3384
3385
3386
3387
3390 else
3391 fallback_to_stderr = true;
3392 }
3393
3394
3396 {
3397
3398
3399
3400
3401
3403 {
3405 }
3406 else
3407 fallback_to_stderr = true;
3408 }
3409
3410
3411
3412
3413
3416 fallback_to_stderr)
3417 {
3418
3419
3420
3421
3422
3425#ifdef WIN32
3426
3427
3428
3429
3430
3431
3432
3433
3435 write_eventlog(edata->elevel, buf.data, buf.len);
3436#endif
3437 else
3439 }
3440
3441
3444
3445
3447}
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469void
3471{
3473 int fd = fileno(stderr);
3474 int rc;
3475
3477
3487
3488
3490 {
3491
3495 (void) rc;
3498 }
3499
3500
3505 (void) rc;
3506}
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520static void
3522{
3525 else
3527}
3528
3529
3530
3531
3532static void
3534{
3536
3537
3538
3539
3540
3541
3542
3543
3545 {
3546
3547 const char *sev;
3548 char tbuf[12];
3549
3550
3553 else
3555
3561
3564
3565
3569 else
3571
3573 {
3576 }
3577
3578
3579
3580 if (edata->hint)
3581 {
3584 }
3585
3587 {
3590 }
3591
3593 {
3596 }
3597
3599 {
3602 }
3603
3605 {
3608 }
3609
3611 {
3614 }
3615
3617 {
3620 }
3621
3623 {
3627 }
3628
3630 {
3634 }
3635
3637 {
3640 }
3641
3643 {
3646 }
3647
3648 if (edata->lineno > 0)
3649 {
3653 }
3654
3656 {
3659 }
3660
3661 pq_sendbyte(&msgbuf, '\0');
3662
3664 }
3665 else
3666 {
3667
3669
3671
3673
3676 else
3678
3680
3681
3683
3685 }
3686
3687
3688
3689
3690
3691
3692
3693
3694
3696}
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710const char *
3712{
3713 const char *prefix;
3714
3715 switch (elevel)
3716 {
3723 break;
3724 case LOG:
3727 break;
3730 break;
3733 break;
3737 break;
3740 break;
3743 break;
3746 break;
3747 default:
3748 prefix = "???";
3749 break;
3750 }
3751
3752 return prefix;
3753}
3754
3755
3756
3757
3758
3759
3760
3761
3762static void
3764{
3765 char ch;
3766
3767 while ((ch = *str++) != '\0')
3768 {
3770 if (ch == '\n')
3772 }
3773}
3774
3775
3776
3777
3778
3779
3780
3781void
3783{
3784 va_list ap;
3785
3786#ifdef WIN32
3787 char errbuf[2048];
3788#endif
3789
3790 fmt = _(fmt);
3791
3792 va_start(ap, fmt);
3793#ifndef WIN32
3794
3796 fflush(stderr);
3797#else
3798 vsnprintf(errbuf, sizeof(errbuf), fmt, ap);
3799
3800
3801
3802
3803
3805 {
3806 write_eventlog(ERROR, errbuf, strlen(errbuf));
3807 }
3808 else
3809 {
3810
3812 fflush(stderr);
3813 }
3814#endif
3815 va_end(ap);
3816}
void ExceptionalCondition(const char *conditionName, const char *fileName, int lineNumber)
uint64 pgstat_get_my_query_id(void)
#define pg_attribute_format_arg(a)
#define pg_attribute_cold
#define PG_TEXTDOMAIN(domain)
#define MemSet(start, val, len)
void write_csvlog(ErrorData *edata)
void assign_syslog_facility(int newval, void *extra)
int getinternalerrposition(void)
static bool should_output_to_client(int elevel)
void assign_syslog_ident(const char *newval, void *extra)
int errcode_for_socket_access(void)
bool errsave_start(struct Node *context, const char *domain)
static void log_line_prefix(StringInfo buf, ErrorData *edata)
static const char * process_log_prefix_padding(const char *p, int *ppadding)
int err_generic_string(int field, const char *str)
int errmsg_plural(const char *fmt_singular, const char *fmt_plural, unsigned long n,...)
void errsave_finish(struct Node *context, const char *filename, int lineno, const char *funcname)
static char formatted_log_time[FORMATTED_TS_LEN]
int internalerrquery(const char *query)
static char formatted_start_time[FORMATTED_TS_LEN]
int internalerrposition(int cursorpos)
static void send_message_to_frontend(ErrorData *edata)
bool check_log_of_query(ErrorData *edata)
int errmsg_internal(const char *fmt,...)
static void append_with_tabs(StringInfo buf, const char *str)
char * format_elog_string(const char *fmt,...)
int errhidestmt(bool hide_stmt)
bool errstart(int elevel, const char *domain)
void EmitErrorReport(void)
bool syslog_split_messages
static void FreeErrorDataContents(ErrorData *edata)
static int errordata_stack_depth
char * GetErrorContextStack(void)
static void err_sendstring(StringInfo buf, const char *str)
void FreeErrorData(ErrorData *edata)
void assign_backtrace_functions(const char *newval, void *extra)
const char * error_severity(int elevel)
static ErrorData * get_error_stack_entry(void)
int errdetail_internal(const char *fmt,...)
static bool saved_timeval_set
int errcode_for_file_access(void)
static char * backtrace_function_list
int errdetail(const char *fmt,...)
int errcontext_msg(const char *fmt,...)
static int save_format_errnumber
bool check_backtrace_functions(char **newval, void **extra, GucSource source)
void pre_format_elog_string(int errnumber, const char *domain)
static int recursion_depth
ErrorContextCallback * error_context_stack
int errhint_internal(const char *fmt,...)
static struct timeval saved_timeval
void ReThrowError(ErrorData *edata)
static void set_errdata_field(MemoryContextData *cxt, char **ptr, const char *str)
char * get_formatted_start_time(void)
static bool matches_backtrace_functions(const char *funcname)
ErrorData * CopyErrorData(void)
bool check_log_destination(char **newval, void **extra, GucSource source)
void FlushErrorState(void)
int errdetail_plural(const char *fmt_singular, const char *fmt_plural, unsigned long n,...)
int errhint(const char *fmt,...)
static bool is_log_level_output(int elevel, int log_min_level)
void ThrowErrorData(ErrorData *edata)
bool message_level_is_interesting(int elevel)
void write_pipe_chunks(char *data, int len, int dest)
int errhidecontext(bool hide_ctx)
emit_log_hook_type emit_log_hook
bool syslog_sequence_numbers
static void send_message_to_server_log(ErrorData *edata)
char * Log_destination_string
static void write_console(const char *line, int len)
#define EVALUATE_MESSAGE(domain, targetfield, appendval, translateit)
static void set_stack_entry_location(ErrorData *edata, const char *filename, int lineno, const char *funcname)
pg_attribute_cold bool errstart_cold(int elevel, const char *domain)
#define CHECK_STACK_DEPTH()
static void set_stack_entry_domain(ErrorData *edata, const char *domain)
#define EVALUATE_MESSAGE_PLURAL(domain, targetfield, appendval)
static bool should_output_to_server(int elevel)
const char * get_backend_type_for_log(void)
int errcode(int sqlerrcode)
int errdetail_log_plural(const char *fmt_singular, const char *fmt_plural, unsigned long n,...)
void write_stderr(const char *fmt,...)
int errmsg(const char *fmt,...)
void log_status_format(StringInfo buf, const char *format, ErrorData *edata)
char * get_formatted_log_time(void)
bool in_error_recursion_trouble(void)
void errfinish(const char *filename, int lineno, const char *funcname)
static const char * err_gettext(const char *str) pg_attribute_format_arg(1)
int errposition(int cursorpos)
#define ERRORDATA_STACK_SIZE
int errhint_plural(const char *fmt_singular, const char *fmt_plural, unsigned long n,...)
int errdetail_log(const char *fmt,...)
char * unpack_sql_state(int sql_state)
static pg_noinline void set_backtrace(ErrorData *edata, int num_skip)
int set_errcontext_domain(const char *domain)
void reset_formatted_start_time(void)
static ErrorData errordata[ERRORDATA_STACK_SIZE]
sigjmp_buf * PG_exception_stack
static const char * save_format_domain
void assign_log_destination(const char *newval, void *extra)
void(* emit_log_hook_type)(ErrorData *edata)
#define WARNING_CLIENT_ONLY
#define LOG_DESTINATION_JSONLOG
#define LOG_DESTINATION_SYSLOG
#define LOG_DESTINATION_STDERR
#define ereport(elevel,...)
#define LOG_DESTINATION_EVENTLOG
#define LOG_DESTINATION_CSVLOG
#define palloc_object(type)
volatile uint32 QueryCancelHoldoffCount
ProtocolVersion FrontendProtocol
volatile uint32 InterruptHoldoffCount
volatile uint32 CritSectionCount
char OutputFileName[MAXPGPATH]
void * guc_malloc(int elevel, size_t size)
#define GUC_check_errdetail
int log_min_error_statement
static int syslog_facility
char * backtrace_functions
Assert(PointerIsAligned(start, uint64))
int pg_getnameinfo_all(const struct sockaddr_storage *addr, int salen, char *node, int nodelen, char *service, int servicelen, int flags)
bool proc_exit_inprogress
void write_jsonlog(ErrorData *edata)
void list_free(List *list)
int pg_mbcliplen(const char *mbstr, int len, int limit)
int GetMessageEncoding(void)
char * MemoryContextStrdup(MemoryContext context, const char *string)
void MemoryContextReset(MemoryContext context)
char * pstrdup(const char *in)
void pfree(void *pointer)
MemoryContext CurrentMemoryContext
MemoryContext ErrorContext
#define CHECK_FOR_INTERRUPTS()
const char * GetBackendTypeDesc(BackendType backendType)
BackendType MyBackendType
#define IsA(nodeptr, _type_)
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
#define DEFAULT_EVENT_SOURCE
static rewind_source * source
SessionEndType pgStatSessionEndCause
size_t pg_strftime(char *s, size_t maxsize, const char *format, const struct pg_tm *t)
struct pg_tm * pg_localtime(const pg_time_t *timep, const pg_tz *tz)
PGDLLIMPORT pg_tz * log_timezone
#define ALL_CONNECTION_FAILURE_ERRNOS
int pg_strcasecmp(const char *s1, const char *s2)
CommandDest whereToSendOutput
const char * debug_query_string
#define PG_DIAG_INTERNAL_QUERY
#define PG_DIAG_SCHEMA_NAME
#define PG_DIAG_CONSTRAINT_NAME
#define PG_DIAG_DATATYPE_NAME
#define PG_DIAG_SOURCE_LINE
#define PG_DIAG_STATEMENT_POSITION
#define PG_DIAG_SOURCE_FILE
#define PG_DIAG_MESSAGE_HINT
#define PG_DIAG_SEVERITY_NONLOCALIZED
#define PG_DIAG_TABLE_NAME
#define PG_DIAG_MESSAGE_PRIMARY
#define PG_DIAG_COLUMN_NAME
#define PG_DIAG_MESSAGE_DETAIL
#define PG_DIAG_SOURCE_FUNCTION
#define PG_DIAG_INTERNAL_POSITION
bool ClientAuthInProgress
BackgroundWorker * MyBgworkerEntry
int pq_putmessage_v2(char msgtype, const char *s, size_t len)
#define PG_PROTOCOL_MAJOR(v)
void pq_sendstring(StringInfo buf, const char *str)
void pq_endmessage(StringInfo buf)
void pq_beginmessage(StringInfo buf, char msgtype)
void pq_send_ascii_string(StringInfo buf, const char *str)
static void pq_sendbyte(StringInfo buf, uint8 byt)
static int fd(const char *x, int i)
#define INVALID_PROC_NUMBER
#define PqMsg_ErrorResponse
#define PqMsg_NoticeResponse
const char * get_ps_display(int *displen)
char * psprintf(const char *fmt,...)
void appendStringInfo(StringInfo str, const char *fmt,...)
void appendBinaryStringInfo(StringInfo str, const void *data, int datalen)
void appendStringInfoSpaces(StringInfo str, int count)
void appendStringInfoString(StringInfo str, const char *s)
void appendStringInfoChar(StringInfo str, char ch)
void initStringInfo(StringInfo str)
#define appendStringInfoCharMacro(str, ch)
char bgw_type[BGW_MAXLEN]
struct ErrorContextCallback * previous
void(* callback)(void *arg)
struct MemoryContextData * assoc_context
const char * context_domain
struct sockaddr_storage addr
void write_syslogger_file(const char *buffer, int count, int destination)
#define PIPE_PROTO_DEST_JSONLOG
#define PIPE_PROTO_IS_LAST
#define PIPE_PROTO_DEST_CSVLOG
#define PIPE_PROTO_DEST_STDERR
bool SplitIdentifierString(char *rawstring, char separator, List **namelist)
int pgwin32_is_service(void)
int gettimeofday(struct timeval *tp, void *tzp)
TransactionId GetTopTransactionIdIfAny(void)