package pgproto3
import (
)
type tracer struct {
TracerOptions
mux sync.Mutex
w io.Writer
buf *bytes.Buffer
}
type TracerOptions struct {
SuppressTimestamps bool
RegressMode bool
}
func ( *tracer) ( byte, int32, Message) {
switch msg := .(type) {
case *AuthenticationCleartextPassword:
.traceAuthenticationCleartextPassword(, , )
case *AuthenticationGSS:
.traceAuthenticationGSS(, , )
case *AuthenticationGSSContinue:
.traceAuthenticationGSSContinue(, , )
case *AuthenticationMD5Password:
.traceAuthenticationMD5Password(, , )
case *AuthenticationOk:
.traceAuthenticationOk(, , )
case *AuthenticationSASL:
.traceAuthenticationSASL(, , )
case *AuthenticationSASLContinue:
.traceAuthenticationSASLContinue(, , )
case *AuthenticationSASLFinal:
.traceAuthenticationSASLFinal(, , )
case *BackendKeyData:
.traceBackendKeyData(, , )
case *Bind:
.traceBind(, , )
case *BindComplete:
.traceBindComplete(, , )
case *CancelRequest:
.traceCancelRequest(, , )
case *Close:
.traceClose(, , )
case *CloseComplete:
.traceCloseComplete(, , )
case *CommandComplete:
.traceCommandComplete(, , )
case *CopyBothResponse:
.traceCopyBothResponse(, , )
case *CopyData:
.traceCopyData(, , )
case *CopyDone:
.traceCopyDone(, , )
case *CopyFail:
.traceCopyFail(, , )
case *CopyInResponse:
.traceCopyInResponse(, , )
case *CopyOutResponse:
.traceCopyOutResponse(, , )
case *DataRow:
.traceDataRow(, , )
case *Describe:
.traceDescribe(, , )
case *EmptyQueryResponse:
.traceEmptyQueryResponse(, , )
case *ErrorResponse:
.traceErrorResponse(, , )
case *Execute:
.traceExecute(, , )
case *Flush:
.traceFlush(, , )
case *FunctionCall:
.traceFunctionCall(, , )
case *FunctionCallResponse:
.traceFunctionCallResponse(, , )
case *GSSEncRequest:
.traceGSSEncRequest(, , )
case *NoData:
.traceNoData(, , )
case *NoticeResponse:
.traceNoticeResponse(, , )
case *NotificationResponse:
.traceNotificationResponse(, , )
case *ParameterDescription:
.traceParameterDescription(, , )
case *ParameterStatus:
.traceParameterStatus(, , )
case *Parse:
.traceParse(, , )
case *ParseComplete:
.traceParseComplete(, , )
case *PortalSuspended:
.tracePortalSuspended(, , )
case *Query:
.traceQuery(, , )
case *ReadyForQuery:
.traceReadyForQuery(, , )
case *RowDescription:
.traceRowDescription(, , )
case *SSLRequest:
.traceSSLRequest(, , )
case *StartupMessage:
.traceStartupMessage(, , )
case *Sync:
.traceSync(, , )
case *Terminate:
.traceTerminate(, , )
default:
.writeTrace(, , "Unknown", nil)
}
}
func ( *tracer) ( byte, int32, *AuthenticationCleartextPassword) {
.writeTrace(, , "AuthenticationCleartextPassword", nil)
}
func ( *tracer) ( byte, int32, *AuthenticationGSS) {
.writeTrace(, , "AuthenticationGSS", nil)
}
func ( *tracer) ( byte, int32, *AuthenticationGSSContinue) {
.writeTrace(, , "AuthenticationGSSContinue", nil)
}
func ( *tracer) ( byte, int32, *AuthenticationMD5Password) {
.writeTrace(, , "AuthenticationMD5Password", nil)
}
func ( *tracer) ( byte, int32, *AuthenticationOk) {
.writeTrace(, , "AuthenticationOk", nil)
}
func ( *tracer) ( byte, int32, *AuthenticationSASL) {
.writeTrace(, , "AuthenticationSASL", nil)
}
func ( *tracer) ( byte, int32, *AuthenticationSASLContinue) {
.writeTrace(, , "AuthenticationSASLContinue", nil)
}
func ( *tracer) ( byte, int32, *AuthenticationSASLFinal) {
.writeTrace(, , "AuthenticationSASLFinal", nil)
}
func ( *tracer) ( byte, int32, *BackendKeyData) {
.writeTrace(, , "BackendKeyData", func() {
if .RegressMode {
.buf.WriteString("\t NNNN NNNN")
} else {
fmt.Fprintf(.buf, "\t %d %d", .ProcessID, .SecretKey)
}
})
}
func ( *tracer) ( byte, int32, *Bind) {
.writeTrace(, , "Bind", func() {
fmt.Fprintf(.buf, "\t %s %s %d", traceDoubleQuotedString([]byte(.DestinationPortal)), traceDoubleQuotedString([]byte(.PreparedStatement)), len(.ParameterFormatCodes))
for , := range .ParameterFormatCodes {
fmt.Fprintf(.buf, " %d", )
}
fmt.Fprintf(.buf, " %d", len(.Parameters))
for , := range .Parameters {
fmt.Fprintf(.buf, " %s", traceSingleQuotedString())
}
fmt.Fprintf(.buf, " %d", len(.ResultFormatCodes))
for , := range .ResultFormatCodes {
fmt.Fprintf(.buf, " %d", )
}
})
}
func ( *tracer) ( byte, int32, *BindComplete) {
.writeTrace(, , "BindComplete", nil)
}
func ( *tracer) ( byte, int32, *CancelRequest) {
.writeTrace(, , "CancelRequest", nil)
}
func ( *tracer) ( byte, int32, *Close) {
.writeTrace(, , "Close", nil)
}
func ( *tracer) ( byte, int32, *CloseComplete) {
.writeTrace(, , "CloseComplete", nil)
}
func ( *tracer) ( byte, int32, *CommandComplete) {
.writeTrace(, , "CommandComplete", func() {
fmt.Fprintf(.buf, "\t %s", traceDoubleQuotedString(.CommandTag))
})
}
func ( *tracer) ( byte, int32, *CopyBothResponse) {
.writeTrace(, , "CopyBothResponse", nil)
}
func ( *tracer) ( byte, int32, *CopyData) {
.writeTrace(, , "CopyData", nil)
}
func ( *tracer) ( byte, int32, *CopyDone) {
.writeTrace(, , "CopyDone", nil)
}
func ( *tracer) ( byte, int32, *CopyFail) {
.writeTrace(, , "CopyFail", func() {
fmt.Fprintf(.buf, "\t %s", traceDoubleQuotedString([]byte(.Message)))
})
}
func ( *tracer) ( byte, int32, *CopyInResponse) {
.writeTrace(, , "CopyInResponse", nil)
}
func ( *tracer) ( byte, int32, *CopyOutResponse) {
.writeTrace(, , "CopyOutResponse", nil)
}
func ( *tracer) ( byte, int32, *DataRow) {
.writeTrace(, , "DataRow", func() {
fmt.Fprintf(.buf, "\t %d", len(.Values))
for , := range .Values {
if == nil {
.buf.WriteString(" -1")
} else {
fmt.Fprintf(.buf, " %d %s", len(), traceSingleQuotedString())
}
}
})
}
func ( *tracer) ( byte, int32, *Describe) {
.writeTrace(, , "Describe", func() {
fmt.Fprintf(.buf, "\t %c %s", .ObjectType, traceDoubleQuotedString([]byte(.Name)))
})
}
func ( *tracer) ( byte, int32, *EmptyQueryResponse) {
.writeTrace(, , "EmptyQueryResponse", nil)
}
func ( *tracer) ( byte, int32, *ErrorResponse) {
.writeTrace(, , "ErrorResponse", nil)
}
func ( *tracer) ( byte, int32, *Execute) {
.writeTrace(, , "Execute", func() {
fmt.Fprintf(.buf, "\t %s %d", traceDoubleQuotedString([]byte(.Portal)), .MaxRows)
})
}
func ( *tracer) ( byte, int32, *Flush) {
.writeTrace(, , "Flush", nil)
}
func ( *tracer) ( byte, int32, *FunctionCall) {
.writeTrace(, , "FunctionCall", nil)
}
func ( *tracer) ( byte, int32, *FunctionCallResponse) {
.writeTrace(, , "FunctionCallResponse", nil)
}
func ( *tracer) ( byte, int32, *GSSEncRequest) {
.writeTrace(, , "GSSEncRequest", nil)
}
func ( *tracer) ( byte, int32, *NoData) {
.writeTrace(, , "NoData", nil)
}
func ( *tracer) ( byte, int32, *NoticeResponse) {
.writeTrace(, , "NoticeResponse", nil)
}
func ( *tracer) ( byte, int32, *NotificationResponse) {
.writeTrace(, , "NotificationResponse", func() {
fmt.Fprintf(.buf, "\t %d %s %s", .PID, traceDoubleQuotedString([]byte(.Channel)), traceDoubleQuotedString([]byte(.Payload)))
})
}
func ( *tracer) ( byte, int32, *ParameterDescription) {
.writeTrace(, , "ParameterDescription", nil)
}
func ( *tracer) ( byte, int32, *ParameterStatus) {
.writeTrace(, , "ParameterStatus", func() {
fmt.Fprintf(.buf, "\t %s %s", traceDoubleQuotedString([]byte(.Name)), traceDoubleQuotedString([]byte(.Value)))
})
}
func ( *tracer) ( byte, int32, *Parse) {
.writeTrace(, , "Parse", func() {
fmt.Fprintf(.buf, "\t %s %s %d", traceDoubleQuotedString([]byte(.Name)), traceDoubleQuotedString([]byte(.Query)), len(.ParameterOIDs))
for , := range .ParameterOIDs {
fmt.Fprintf(.buf, " %d", )
}
})
}
func ( *tracer) ( byte, int32, *ParseComplete) {
.writeTrace(, , "ParseComplete", nil)
}
func ( *tracer) ( byte, int32, *PortalSuspended) {
.writeTrace(, , "PortalSuspended", nil)
}
func ( *tracer) ( byte, int32, *Query) {
.writeTrace(, , "Query", func() {
fmt.Fprintf(.buf, "\t %s", traceDoubleQuotedString([]byte(.String)))
})
}
func ( *tracer) ( byte, int32, *ReadyForQuery) {
.writeTrace(, , "ReadyForQuery", func() {
fmt.Fprintf(.buf, "\t %c", .TxStatus)
})
}
func ( *tracer) ( byte, int32, *RowDescription) {
.writeTrace(, , "RowDescription", func() {
fmt.Fprintf(.buf, "\t %d", len(.Fields))
for , := range .Fields {
fmt.Fprintf(.buf, ` %s %d %d %d %d %d %d`, traceDoubleQuotedString(.Name), .TableOID, .TableAttributeNumber, .DataTypeOID, .DataTypeSize, .TypeModifier, .Format)
}
})
}
func ( *tracer) ( byte, int32, *SSLRequest) {
.writeTrace(, , "SSLRequest", nil)
}
func ( *tracer) ( byte, int32, *StartupMessage) {
.writeTrace(, , "StartupMessage", nil)
}
func ( *tracer) ( byte, int32, *Sync) {
.writeTrace(, , "Sync", nil)
}
func ( *tracer) ( byte, int32, *Terminate) {
.writeTrace(, , "Terminate", nil)
}
func ( *tracer) ( byte, int32, string, func()) {
.mux.Lock()
defer .mux.Unlock()
defer func() {
if .buf.Cap() > 1024 {
.buf = &bytes.Buffer{}
} else {
.buf.Reset()
}
}()
if !.SuppressTimestamps {
:= time.Now()
.buf.WriteString(.Format("2006-01-02 15:04:05.000000"))
.buf.WriteByte('\t')
}
.buf.WriteByte()
.buf.WriteByte('\t')
.buf.WriteString()
.buf.WriteByte('\t')
.buf.WriteString(strconv.FormatInt(int64(), 10))
if != nil {
()
}
.buf.WriteByte('\n')
.buf.WriteTo(.w)
}
func ( []byte) string {
return `"` + string() + `"`
}
func ( []byte) string {
:= &strings.Builder{}
.WriteByte('\'')
for , := range {
if < 32 || > 126 {
fmt.Fprintf(, `\x%x`, )
} else {
.WriteByte()
}
}
.WriteByte('\'')
return .String()
}