Logging is supported by providing a Logger from SwiftLog to the
relevant configuration object.
For the client:
ClientConnection.Builder.withBackgroundActivityLogger allows a logger to be
supplied which logs information at the connection level, relating to things
such as connectivity state changes, or connection errors.CallOptions allows logger to be specified. It is used to log information
at the RPC level, such as changes to the state of the RPC. Any connection
level metadata will be attached to the logger so that RPC logs may be
correlated with connection level changes.For the server:
Server.Builder.withLogger allows a logger to be specified. It is used as a
root logger and is passed down to each accepted connection and in turn each
RPC on a connection. The logger is made available in the context of each
RPC handler.Note that gRPC will not emit logs unless a logger is explicitly provided.
For the client:
If logger is set in the CallOptions for an RPC then gRPC may attach a
request ID to the metadata of that logger. This is determined by the value of
requestIDProvider in CallOptions. The options for requestIDProvider
include:
autogenerated: a new UUID will be generated (default).generated(_:): the provided callback will be called to generate a new ID.userDefined(_:): the provided value will be used. Note: this option should
not be set as a default option on a client as all RPCs would used the same ID.none: no request ID will be attached to the logger, this can be useful if a
logger already has a request ID associated with it.If a request ID is attached to the logger's metadata it will use the key
grpc_request_id.
If a request ID is provided and the requestIDHeader option is set then gRPC
will add the ID to the request headers. By default requestIDHeader is not set.
The ClientConnection is intended to be used as a long-living connection to a
remote peer. It will manage the underlying network resources automatically,
creating a connection when necessary and dropping it when it is no longer
required. However, the user must close() the connection when finished with it.
The underlying connection may be in any of the following states:
The gRPC library documents these states in more details. Note that not all information linked is applicable to gRPC Swift.
A connectivity state delegate may be set using
withConnectivityStateDelegate(_:executingOn:) on the
ClientConnection.Builder.
The delegate is called on the DispatchQueue specified by the executingOn
parameter. gRPC will create a DispatchQueue if one isn't otherwise specified.
These state changes will also be logged by the backgroundActivityLogger (see
above).
The connection will be idled (i.e. the underlying connection closed and moved to
the 'idle' state) if there are no outstanding RPCs for 5 minutes (by default).
The connection will not be idled if there outstanding RPCs which are not
sending or receiving messages. This option may be configured using
withConnectionIdleTimeout on the ClientConnection.Builder.
Any RPC called after the connection has idled will trigger a connection attempt.
For long-lived, low-activity RPCs it may be beneficial to configure keepalive. Doing so will periodically send pings to the remote peer. It may also be used to detect unresponsive peers.
See the gRPC Keepalive documentation for details.
RPCs are usually started by invoking a method on a generated client. Each
generated client relies on an underlying GRPCChannel to provide transport.
RPCs can also be made without a generated client by using AnyServiceClient.
This requires the user know the path (i.e. '/echo/Get') and request and response
types for the RPC.
RPCs are never automatically retried by gRPC Swift.
The framework cannot determine whether your RPC is idempotent, it is therefore not safe for gRPC Swift to automatically retry RPCs for you.
It's recommended that deadlines are used to enforce a limit on the duration of
an RPC. Users may set a time limit (either a deadline or a timeout) on the
CallOptions for each call, or as a default on a client. RPCs which have not
completed before the time limit will be failed with status code 4
('deadline exceeded').
gRPC Swift supports compression.
You can configure compression via the messageEncoding property on CallOptions:
// Configure encoding
let encodingConfiguration = ClientMessageEncoding.Configuration(
forRequests: .gzip, // use gzip for requests
acceptableForResponses: .all, // accept all supported algorithms for responses
decompressionLimit: .ratio(20) // reject messages and fail the RPC if a response decompresses to over 20x its compressed size
)
// Enable compression with configuration
let options = CallOptions(messageEncoding: .enabled(encodingConfiguration))
// Use the options to make a request
let rpc = echo.get(request, callOptions: options)
// ...