blob: b26f4c1e7c285b981be66f03c016b757a4a09793 [file] [log] [blame]
= Request Tracing
[[on-demand]]
== On-demand Request Tracing
Gerrit supports on-demand tracing of single requests that results in
additional logs with debug information that are written to the
`error_log`. The logs that correspond to a traced request are
associated with a unique trace ID. This trace ID is returned with the
response and can be used by an administrator to find the matching log
entries.
How tracing is enabled and how the trace ID is returned depends on the
request type:
* REST API: For REST calls tracing can be enabled by setting the
`trace` request parameter or the `X-Gerrit-Trace` header, the trace
ID is returned as `X-Gerrit-Trace` header. More information about
this can be found in the link:rest-api.html#tracing[Request Tracing]
section of the link:rest-api.html[REST API documentation].
* SSH API: For SSH calls tracing can be enabled by setting the
`--trace` option. More information about this can be found in
the link:cmd-index.html#trace[Trace] section of the
link:cmd-index.html[SSH command documentation].
* Git Push (requires usage of git protocol v2): For Git pushes tracing
can be enabled by setting the `trace` push option, the trace ID is
returned in the command output. More information about this can be
found in the link:user-upload.html#trace[Trace] section of the
link:user-upload.html[upload documentation].
* Git Clone/Fetch/Ls-Remote (requires usage of git protocol v2): For
Git clone/fetch/ls-remote tracing can be enabled by setting the
`trace` server option. Use '-o trace=<TRACE-ID>' for `git fetch` and
`git ls-remote`, and '--server-option trace=<TRACE-ID>' for
`git clone`. If the `trace` server option is set without a value
(without trace ID) a trace ID is generated but the generated trace ID
is not returned to the client (hence a trace ID should always be
set).
When request tracing is enabled it is possible to provide an ID that
should be used as trace ID. If a trace ID is not provided a trace ID is
automatically generated. The trace ID must be provided to the support
team (administrator of the server) so that they can find the trace.
When doing traces it is recommended to specify the ID of the issue
that is being investigated as trace ID so that the traces of the issue
can be found more easily. When the issue ID is used as trace ID there
is no need to find the generated trace ID and report it in the issue.
Since tracing consumes additional server resources tracing should only
be enabled for single requests if there is a concrete need for
debugging. In particular bots should never enable tracing for all their
requests by default.
[[auto-retry]]
== Automatic Request Tracing
Gerrit can be link:config-gerrit.html#retry.retryWithTraceOnFailure[
configured] to automatically retry requests on non-recoverable failures
with tracing enabled. This allows to automatically captures traces of
these failures for further analysis by the Gerrit administrators.
The auto-retry on failure behaves the same way as if the calling user
would retry the failed operation with tracing enabled.
It is expected that the auto-retry fails with the same exception that
triggered the auto-retry, however this is not guaranteed:
* Not all Gerrit operations are fully atomic and it can happen that
some parts of the operation have been successfully performed before
the failure happened. In this case the auto-retry may fail with a
different exception.
* Some exceptions may mistakenly be considered as non-recoverable and
the auto-retry actually succeeds.
[[auto-retry-succeeded]]
If an auto-retry succeeds you may consider filing this as
link:https://bugs.chromium.org/p/gerrit/issues/entry?template=GoogleSource+Issue[
Gerrit issue] so that the Gerrit developers can fix this and treat this
exception as recoverable.
The trace IDs for auto-retries are generated and start with
`retry-on-failure-`. For REST requests they are returned to the client
as `X-Gerrit-Trace` header.
The best way to search for auto-retries in logs is to do a grep by
`AutoRetry`. For each auto-retry that happened this should match 1 or 2
log entries:
* one `ERROR` log entry with the exception that triggered the
auto-retry
* one `FINE` log entry with the exception that happened on auto-retry
(if this log entry is not present the operation succeeded on
auto-retry)
To inspect single auto-retry occurrences in detail you can do a
link:#find-trace[grep by the trace ID]. The trace ID is part of the log
entries which have been found by the previous grep (watch out for
something like: `retry-on-failure-1534166888910-3985dfba`).
[TIP]
Auto-retrying on failures is only supported by some of the REST
endpoints (change REST endpoints that perform updates).
[[auto-retry-metrics]]
=== Metrics
If auto-retry is link:config-gerrit.html#retry.retryWithTraceOnFailure[
enabled] the following metrics are reported:
* `action/auto_retry_count`: Number of automatic retries with tracing
* `action/failures_on_auto_retry_count`: Number of failures on auto retry
By comparing the values of these counters one can see how often the
auto-retry succeeds. As explained link:#auto-retry-succeeded[above] if
auto-retries succeed that's an issue with Gerrit that you may want to
report.
[[find-trace]]
== Find log entries for a trace ID
If tracing is enabled all log messages that correspond to the traced
request have a `TRACE_ID` tag set, e.g.:
----
[2018-08-13 15:28:08,913] [HTTP-76] TRACE com.google.gerrit.httpd.restapi.RestApiServlet : Received REST request: GET /a/accounts/self (parameters: [trace]) [CONTEXT forced=true TRACE_ID="1534166888910-3985dfba" ]
[2018-08-13 15:28:08,914] [HTTP-76] TRACE com.google.gerrit.httpd.restapi.RestApiServlet : Calling user: admin [CONTEXT forced=true TRACE_ID="1534166888910-3985dfba" ]
[2018-08-13 15:28:08,942] [HTTP-76] TRACE com.google.gerrit.httpd.restapi.RestApiServlet : REST call succeeded: 200 [CONTEXT forced=true TRACE_ID="1534166888910-3985dfba" ]
----
By doing a grep with the trace ID over the error log the log entries
that correspond to the request can be found.
[TIP]
Usually only server administrators have access to the logs.
== Which information is captured in a trace?
* request details
** REST API: request URL, request parameter names, calling user,
response code, response body on errors
** SSH API: parameter names
** Git API: push options, magic branch parameter names
* cache misses, cache evictions
* reads from NoteDb, writes to NoteDb
* reads of meta data files, writes of meta data files
* index queries (with parameters and matches)
* reindex events
* permission checks (e.g. which rule is responsible for a deny)
* timer metrics
* all other logs