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

Commit 198b371

Browse files
committed
Improve PQtrace() output format
Transform the PQtrace output format from its ancient (and mostly useless) byte-level output format to a logical-message-level output, making it much more usable. This implementation allows the printing code to be written (as it indeed was) by looking at the protocol documentation, which gives more confidence that the three (docs, trace code and actual code) actually match. Author: 岩田 彩 (Aya Iwata) <iwata.aya@fujitsu.com> Reviewed-by: 綱川 貴之 (Takayuki Tsunakawa) <tsunakawa.takay@fujitsu.com> Reviewed-by: Kirk Jamison <k.jamison@fujitsu.com> Reviewed-by: Kyotaro Horiguchi <horikyota.ntt@gmail.com> Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us> Reviewed-by: 黒田 隼人 (Hayato Kuroda) <kuroda.hayato@fujitsu.com> Reviewed-by: "Nagaura, Ryohei" <nagaura.ryohei@jp.fujitsu.com> Reviewed-by: Ryo Matsumura <matsumura.ryo@fujitsu.com> Reviewed-by: Greg Nancarrow <gregn4422@gmail.com> Reviewed-by: Jim Doty <jdoty@pivotal.io> Reviewed-by: Álvaro Herrera <alvherre@alvh.no-ip.org> Discussion: https://postgr.es/m/71E660EB361DF14299875B198D4CE5423DE3FBA4@g01jpexmbkw25
1 parent 5da9868 commit 198b371

File tree

10 files changed

+804
-82
lines changed

10 files changed

+804
-82
lines changed

doc/src/sgml/libpq.sgml

+41-1
Original file line numberDiff line numberDiff line change
@@ -6459,12 +6459,27 @@ PGContextVisibility PQsetErrorContextVisibility(PGconn *conn, PGContextVisibilit
64596459

64606460
<listitem>
64616461
<para>
6462-
Enables tracing of the client/server communication to a debugging file stream.
6462+
Enables tracing of the client/server communication to a debugging file
6463+
stream.
64636464
<synopsis>
64646465
void PQtrace(PGconn *conn, FILE *stream);
64656466
</synopsis>
64666467
</para>
64676468

6469+
<para>
6470+
Each line consists of: an optional timestamp, a direction indicator
6471+
(<literal>F</literal> for messages from client to server
6472+
or <literal>B</literal> for messages from server to client),
6473+
message length, message type, and message contents.
6474+
Non-message contents fields (timestamp, direction, length and message type)
6475+
are separated by a tab. Message contents are separated by a space.
6476+
Protocol strings are enclosed in double quotes, while strings used as data
6477+
values are enclosed in single quotes. Non-printable chars are printed as
6478+
hexadecimal escapes.
6479+
Further message-type-specific detail can be found in
6480+
<xref linkend="protocol-message-formats"/>.
6481+
</para>
6482+
64686483
<note>
64696484
<para>
64706485
On Windows, if the <application>libpq</application> library and an application are
@@ -6479,6 +6494,31 @@ void PQtrace(PGconn *conn, FILE *stream);
64796494
</listitem>
64806495
</varlistentry>
64816496

6497+
<varlistentry id="libpq-PQtraceSetFlags">
6498+
<term><function>PQtraceSetFlags</function><indexterm><primary>PQtraceSetFlags</primary></indexterm></term>
6499+
6500+
<listitem>
6501+
<para>
6502+
Controls the tracing behavior of client/server communication.
6503+
<synopsis>
6504+
void PQtraceSetFlags(PGconn *conn, int flags);
6505+
</synopsis>
6506+
</para>
6507+
6508+
<para>
6509+
<literal>flags</literal> contains flag bits describing the operating mode
6510+
of tracing.
6511+
If <literal>flags</literal> contains <literal>PQTRACE_SUPPRESS_TIMESTAMPS</literal>,
6512+
then the timestamp is not included when printing each message.
6513+
If <literal>flags</literal> contains <literal>PQTRACE_REGRESS_MODE</literal>,
6514+
then some fields are redacted when printing each message, such as object
6515+
OIDs, to make the output more convenient to use in testing frameworks.
6516+
This function must be called after calling <function>PQtrace</function>.
6517+
</para>
6518+
6519+
</listitem>
6520+
</varlistentry>
6521+
64826522
<varlistentry id="libpq-PQuntrace">
64836523
<term><function>PQuntrace</function><indexterm><primary>PQuntrace</primary></indexterm></term>
64846524

src/interfaces/libpq/Makefile

+1
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ OBJS = \
3939
fe-print.o \
4040
fe-protocol3.o \
4141
fe-secure.o \
42+
fe-trace.o \
4243
legacy-pqsignal.o \
4344
libpq-events.o \
4445
pqexpbuffer.o \

src/interfaces/libpq/exports.txt

+1
Original file line numberDiff line numberDiff line change
@@ -183,3 +183,4 @@ PQenterPipelineMode 180
183183
PQexitPipelineMode 181
184184
PQpipelineSync 182
185185
PQpipelineStatus 183
186+
PQtraceSetFlags 184

src/interfaces/libpq/fe-connect.c

-21
Original file line numberDiff line numberDiff line change
@@ -6859,27 +6859,6 @@ PQsetErrorContextVisibility(PGconn *conn, PGContextVisibility show_context)
68596859
return old;
68606860
}
68616861

6862-
void
6863-
PQtrace(PGconn *conn, FILE *debug_port)
6864-
{
6865-
if (conn == NULL)
6866-
return;
6867-
PQuntrace(conn);
6868-
conn->Pfdebug = debug_port;
6869-
}
6870-
6871-
void
6872-
PQuntrace(PGconn *conn)
6873-
{
6874-
if (conn == NULL)
6875-
return;
6876-
if (conn->Pfdebug)
6877-
{
6878-
fflush(conn->Pfdebug);
6879-
conn->Pfdebug = NULL;
6880-
}
6881-
}
6882-
68836862
PQnoticeReceiver
68846863
PQsetNoticeReceiver(PGconn *conn, PQnoticeReceiver proc, void *arg)
68856864
{

src/interfaces/libpq/fe-exec.c

-4
Original file line numberDiff line numberDiff line change
@@ -970,10 +970,6 @@ pqSaveParameterStatus(PGconn *conn, const char *name, const char *value)
970970
pgParameterStatus *pstatus;
971971
pgParameterStatus *prev;
972972

973-
if (conn->Pfdebug)
974-
fprintf(conn->Pfdebug, "pqSaveParameterStatus: '%s' = '%s'\n",
975-
name, value);
976-
977973
/*
978974
* Forget any old information about the parameter
979975
*/

src/interfaces/libpq/fe-misc.c

+15-51
Original file line numberDiff line numberDiff line change
@@ -84,9 +84,6 @@ pqGetc(char *result, PGconn *conn)
8484

8585
*result = conn->inBuffer[conn->inCursor++];
8686

87-
if (conn->Pfdebug)
88-
fprintf(conn->Pfdebug, "From backend> %c\n", *result);
89-
9087
return 0;
9188
}
9289

@@ -100,9 +97,6 @@ pqPutc(char c, PGconn *conn)
10097
if (pqPutMsgBytes(&c, 1, conn))
10198
return EOF;
10299

103-
if (conn->Pfdebug)
104-
fprintf(conn->Pfdebug, "To backend> %c\n", c);
105-
106100
return 0;
107101
}
108102

@@ -138,10 +132,6 @@ pqGets_internal(PQExpBuffer buf, PGconn *conn, bool resetbuffer)
138132

139133
conn->inCursor = ++inCursor;
140134

141-
if (conn->Pfdebug)
142-
fprintf(conn->Pfdebug, "From backend> \"%s\"\n",
143-
buf->data);
144-
145135
return 0;
146136
}
147137

@@ -167,9 +157,6 @@ pqPuts(const char *s, PGconn *conn)
167157
if (pqPutMsgBytes(s, strlen(s) + 1, conn))
168158
return EOF;
169159

170-
if (conn->Pfdebug)
171-
fprintf(conn->Pfdebug, "To backend> \"%s\"\n", s);
172-
173160
return 0;
174161
}
175162

@@ -188,13 +175,6 @@ pqGetnchar(char *s, size_t len, PGconn *conn)
188175

189176
conn->inCursor += len;
190177

191-
if (conn->Pfdebug)
192-
{
193-
fprintf(conn->Pfdebug, "From backend (%lu)> ", (unsigned long) len);
194-
fwrite(s, 1, len, conn->Pfdebug);
195-
fprintf(conn->Pfdebug, "\n");
196-
}
197-
198178
return 0;
199179
}
200180

@@ -212,13 +192,6 @@ pqSkipnchar(size_t len, PGconn *conn)
212192
if (len > (size_t) (conn->inEnd - conn->inCursor))
213193
return EOF;
214194

215-
if (conn->Pfdebug)
216-
{
217-
fprintf(conn->Pfdebug, "From backend (%lu)> ", (unsigned long) len);
218-
fwrite(conn->inBuffer + conn->inCursor, 1, len, conn->Pfdebug);
219-
fprintf(conn->Pfdebug, "\n");
220-
}
221-
222195
conn->inCursor += len;
223196

224197
return 0;
@@ -234,13 +207,6 @@ pqPutnchar(const char *s, size_t len, PGconn *conn)
234207
if (pqPutMsgBytes(s, len, conn))
235208
return EOF;
236209

237-
if (conn->Pfdebug)
238-
{
239-
fprintf(conn->Pfdebug, "To backend> ");
240-
fwrite(s, 1, len, conn->Pfdebug);
241-
fprintf(conn->Pfdebug, "\n");
242-
}
243-
244210
return 0;
245211
}
246212

@@ -278,9 +244,6 @@ pqGetInt(int *result, size_t bytes, PGconn *conn)
278244
return EOF;
279245
}
280246

281-
if (conn->Pfdebug)
282-
fprintf(conn->Pfdebug, "From backend (#%lu)> %d\n", (unsigned long) bytes, *result);
283-
284247
return 0;
285248
}
286249

@@ -314,9 +277,6 @@ pqPutInt(int value, size_t bytes, PGconn *conn)
314277
return EOF;
315278
}
316279

317-
if (conn->Pfdebug)
318-
fprintf(conn->Pfdebug, "To backend (%lu#)> %d\n", (unsigned long) bytes, value);
319-
320280
return 0;
321281
}
322282

@@ -525,10 +485,6 @@ pqPutMsgStart(char msg_type, PGconn *conn)
525485
conn->outMsgEnd = endPos;
526486
/* length word, if needed, will be filled in by pqPutMsgEnd */
527487

528-
if (conn->Pfdebug)
529-
fprintf(conn->Pfdebug, "To backend> Msg %c\n",
530-
msg_type ? msg_type : ' ');
531-
532488
return 0;
533489
}
534490

@@ -563,10 +519,6 @@ pqPutMsgBytes(const void *buf, size_t len, PGconn *conn)
563519
int
564520
pqPutMsgEnd(PGconn *conn)
565521
{
566-
if (conn->Pfdebug)
567-
fprintf(conn->Pfdebug, "To backend> Msg complete, length %u\n",
568-
conn->outMsgEnd - conn->outCount);
569-
570522
/* Fill in length word if needed */
571523
if (conn->outMsgStart >= 0)
572524
{
@@ -576,6 +528,16 @@ pqPutMsgEnd(PGconn *conn)
576528
memcpy(conn->outBuffer + conn->outMsgStart, &msgLen, 4);
577529
}
578530

531+
/* trace client-to-server message */
532+
if (conn->Pfdebug)
533+
{
534+
if (conn->outCount < conn->outMsgStart)
535+
pqTraceOutputMessage(conn, conn->outBuffer + conn->outCount, true);
536+
else
537+
pqTraceOutputNoTypeByteMessage(conn,
538+
conn->outBuffer + conn->outMsgStart);
539+
}
540+
579541
/* Make message eligible to send */
580542
conn->outCount = conn->outMsgEnd;
581543

@@ -1002,11 +964,13 @@ pqSendSome(PGconn *conn, int len)
1002964
int
1003965
pqFlush(PGconn *conn)
1004966
{
1005-
if (conn->Pfdebug)
1006-
fflush(conn->Pfdebug);
1007-
1008967
if (conn->outCount > 0)
968+
{
969+
if (conn->Pfdebug)
970+
fflush(conn->Pfdebug);
971+
1009972
return pqSendSome(conn, conn->outCount);
973+
}
1010974

1011975
return 0;
1012976
}

src/interfaces/libpq/fe-protocol3.c

+13
Original file line numberDiff line numberDiff line change
@@ -457,6 +457,10 @@ pqParseInput3(PGconn *conn)
457457
/* Successfully consumed this message */
458458
if (conn->inCursor == conn->inStart + 5 + msgLength)
459459
{
460+
/* trace server-to-client message */
461+
if (conn->Pfdebug)
462+
pqTraceOutputMessage(conn, conn->inBuffer + conn->inStart, false);
463+
460464
/* Normal case: parsing agrees with specified length */
461465
conn->inStart = conn->inCursor;
462466
}
@@ -1660,6 +1664,10 @@ getCopyDataMessage(PGconn *conn)
16601664
return -1;
16611665
}
16621666

1667+
/* trace server-to-client message */
1668+
if (conn->Pfdebug)
1669+
pqTraceOutputMessage(conn, conn->inBuffer + conn->inStart, false);
1670+
16631671
/* Drop the processed message and loop around for another */
16641672
conn->inStart = conn->inCursor;
16651673
}
@@ -2119,6 +2127,11 @@ pqFunctionCall3(PGconn *conn, Oid fnid,
21192127
conn->inStart += 5 + msgLength;
21202128
return pqPrepareAsyncResult(conn);
21212129
}
2130+
2131+
/* trace server-to-client message */
2132+
if (conn->Pfdebug)
2133+
pqTraceOutputMessage(conn, conn->inBuffer + conn->inStart, false);
2134+
21222135
/* Completed this message, keep going */
21232136
/* trust the specified message length as what to skip */
21242137
conn->inStart += 5 + msgLength;

0 commit comments

Comments
 (0)