The Hasura GraphQL engine has different kind of log-types depending on the sub-system or the layer. A log-type is simply the ``type`` field in a log line, which indicates which sub-system the log comes from.
For example, the HTTP webserver logs incoming requests as an access log and is called ``http-log``. Similarly logs from the websocket layer are called ``websocket-log``, logs from the event trigger system are called ``event-trigger`` etc.
You can configure the GraphQL engine to enable/disable certain log-types using the the ``--enabled-log-types`` flag or the ``HASURA_GRAPHQL_ENABLED_LOG_TYPES`` env var. See :doc:`../deployment/graphql-engine-flags/reference`
All the log-types that can be enabled/disabled are:
..list-table:: Configurable log-types
:header-rows:1
:widths:10 25 10
* - Log type
- Description
- Log Level
* - ``startup``
- Information that is logged during startup
-``info``
* - ``query-log``
- Logs: the entire GraphQL query with variables, generated SQL statements
(only for queries, not for mutations/subscriptions or remote schema
queries), the operation name (if provided in the GraphQL request)
-``info``
* - ``http-log``
- Http access and error logs at the webserver layer (handling GraphQL and metadata requests)
-``info`` and ``error``
* - ``websocket-log``
- Websocket events and error logs at the websocket server layer (handling GraphQL requests)
-``info`` and ``error``
* - ``webhook-log``
- Logs responses and errors from the authorization webhook (if setup)
-``info`` and ``error``
Apart from the above, there are other internal log-types which cannot be configured:
..list-table:: Internal log-types
:header-rows:1
:widths:10 25 10
* - Log type
- Description
- Log Level
* - ``pg-client``
- Logs from the postgres client library
-``warn``
* - ``metadata``
- Logs inconsistent metadata items
-``warn``
* - ``jwk-refresh-log``
- Logs information and errors about periodic refreshing of JWK
-``info`` and ``error``
* - ``telemetry-log``
- Logs error (if any) while sending out telemetry data
-``info``
* - ``event-trigger``
- Logs HTTP responses from the webhook, HTTP exceptions and internal
errors
-``info`` and ``error``
* - ``ws-server``
- Debug logs from the websocket server, mostly used internally for debugging
-``debug``
* - ``schema-sync-thread``
- Logs internal events, when it detects schema has changed on Postgres and
when it reloads the schema
-``info`` and ``error``
Logging levels
--------------
You can set the desired logging level on the server using the ``log-level`` flag or the ``HASURA_GRAPHQL_LOG_LEVEL`` env var. See :doc:`../deployment/graphql-engine-flags/reference`.
The default log-level is ``info``.
Setting a log-level will print all logs of priority greater than the set level. The log-level hierarchy is: ``debug > info > warn > error``
For example, setting ``--log-level=warn``, will enable all warn and error level logs only. So even if you have enabled ``query-log`` it won't be printed as the level of ``query-log`` is ``info``.
See :ref:`log-types <log-types>` for more details on log-level of each log-type.
Log structure and metrics
-------------------------
All requests are identified by a request id. If the client sends a ``x-request-id`` header then that is used, otherwise a request id is generated for each request. This is also sent back to the client as a response header (``x-request-id``). This is useful to correlate logs from the server and the client.
**query-log** structure
^^^^^^^^^^^^^^^^^^^^^^^
On enabling verbose logging, i.e. enabling ``query-log``,
GraphQL engine will log the full GraphQL query object on each request.
It will also log the generated SQL for GraphQL queries (but not mutations and
"query": "SELECT coalesce(json_agg(\"root\" ), '[]' ) AS \"root\" FROM (SELECT row_to_json((SELECT \"_1_e\" FROM (SELECT \"_0_root.base\".\"username\" AS \"username\" ) AS \"_1_e\" ) ) AS \"root\" FROM (SELECT * FROM \"public\".\"profile\" WHERE ((\"public\".\"profile\".\"username\") LIKE ($2)) ) AS \"_0_root.base\" LIMIT 10 ) AS \"_2_root\" "
"query": "SELECT coalesce(json_agg(\"root\" ), '[]' ) AS \"root\" FROM (SELECT row_to_json((SELECT \"_1_e\" FROM (SELECT \"_0_root.base\".\"username\" AS \"username\" ) AS \"_1_e\" ) ) AS \"root\" FROM (SELECT * FROM \"public\".\"profile\" WHERE ((\"public\".\"profile\".\"username\") = ($2)) ) AS \"_0_root.base\" ) AS \"_2_root\" "
}
}
}
}
The ``type`` of in the log with be ``query-log``. All the details are nested
under the ``detail`` key.
This log contains 3 important fields:
-``request_id``: A unique ID for each request. If the client sends a
``x-request-id`` header then that is respected, otherwise a UUID is generated
for each request. This is useful to correlate between ``http-log`` and
``query-log``.
-``query``: Contains the full GraphQL request including the variables and
operation name.
-``generated_sql``: this contains the generated SQL for GraphQL queries. For
mutations and subscriptions this field will be ``null``.