Copyright | Will Thompson and Iñaki García Etxebarria |
---|---|
License | LGPL-2.1 |
Maintainer | Iñaki García Etxebarria |
Safe Haskell | Safe-Inferred |
Language | Haskell2010 |
Debug logging support
Logger
watches a [classsession
] and logs the HTTP traffic that
it generates, for debugging purposes. Many applications use an
environment variable to determine whether or not to use
Logger
, and to determine the amount of debugging output.
To use Logger
, first create a logger with [ctorlogger
.new], optionally
configure it with [methodlogger
.set_request_filter],
[methodlogger
.set_response_filter], and [methodlogger
.set_printer], and
then attach it to a session (or multiple sessions) with
[methodsession
.add_feature].
By default, the debugging output is sent to stdout
, and looks something
like:
> POST /unauth HTTP/1.1 > Soup-Debug-Timestamp: 1200171744 > Soup-Debug: SoupSession 1 (0x612190), SoupMessage 1 (0x617000), GSocket 1 (0x612220) > Host: localhost > Content-Type: text/plain > Connection: close < HTTP/1.1 201 Created < Soup-Debug-Timestamp: 1200171744 < Soup-Debug: SoupMessage 1 (0x617000) < Date: Sun, 12 Jan 2008 21:02:24 GMT < Content-Length: 0
The Soup-Debug-Timestamp
line gives the time (as a time_t
) when the
request was sent, or the response fully received.
The Soup-Debug
line gives further debugging information about the
[classsession
], [classmessage
], and Socket
involved; the hex
numbers are the addresses of the objects in question (which may be useful if
you are running in a debugger). The decimal IDs are simply counters that
uniquely identify objects across the lifetime of the Logger
. In
particular, this can be used to identify when multiple messages are sent
across the same connection.
Currently, the request half of the message is logged just before
the first byte of the request gets written to the network (from the
signalmessage
[starting] signal).
The response is logged just after the last byte of the response body is read
from the network (from the signalmessage
[gotBody] or
signalmessage
[gotInformational] signal), which means that the
signalmessage
[gotHeaders] signal, and anything triggered off it (such as
Message::authenticate) will be emitted *before* the response headers are
actually logged.
If the response doesn't happen to trigger the signalmessage
[gotBody] nor
signalmessage
[gotInformational] signals due to, for example, a
cancellation before receiving the last byte of the response body, the
response will still be logged on the event of the signalmessage
[finished]
signal.
Synopsis
- newtype Logger = Logger (ManagedPtr Logger)
- class (GObject o, IsDescendantOf Logger o) => IsLogger o
- toLogger :: (MonadIO m, IsLogger o) => o -> m Logger
- loggerGetMaxBodySize :: (HasCallStack, MonadIO m, IsLogger a) => a -> m Int32
- loggerNew :: (HasCallStack, MonadIO m) => LoggerLogLevel -> m Logger
- loggerSetMaxBodySize :: (HasCallStack, MonadIO m, IsLogger a) => a -> Int32 -> m ()
- loggerSetPrinter :: (HasCallStack, MonadIO m, IsLogger a) => a -> LoggerPrinter -> m ()
- loggerSetRequestFilter :: (HasCallStack, MonadIO m, IsLogger a) => a -> LoggerFilter -> m ()
- loggerSetResponseFilter :: (HasCallStack, MonadIO m, IsLogger a) => a -> LoggerFilter -> m ()
- constructLoggerLevel :: (IsLogger o, MonadIO m) => LoggerLogLevel -> m (GValueConstruct o)
- getLoggerLevel :: (MonadIO m, IsLogger o) => o -> m LoggerLogLevel
- setLoggerLevel :: (MonadIO m, IsLogger o) => o -> LoggerLogLevel -> m ()
- constructLoggerMaxBodySize :: (IsLogger o, MonadIO m) => Int32 -> m (GValueConstruct o)
- getLoggerMaxBodySize :: (MonadIO m, IsLogger o) => o -> m Int32
- setLoggerMaxBodySize :: (MonadIO m, IsLogger o) => o -> Int32 -> m ()
Exported types
Memory-managed wrapper type.
Instances
Eq Logger Source # | |
GObject Logger Source # | |
Defined in GI.Soup.Objects.Logger | |
ManagedPtrNewtype Logger Source # | |
Defined in GI.Soup.Objects.Logger toManagedPtr :: Logger -> ManagedPtr Logger | |
TypedObject Logger Source # | |
Defined in GI.Soup.Objects.Logger | |
HasParentTypes Logger Source # | |
Defined in GI.Soup.Objects.Logger | |
IsGValue (Maybe Logger) Source # | Convert |
Defined in GI.Soup.Objects.Logger gvalueGType_ :: IO GType gvalueSet_ :: Ptr GValue -> Maybe Logger -> IO () gvalueGet_ :: Ptr GValue -> IO (Maybe Logger) | |
type ParentTypes Logger Source # | |
Defined in GI.Soup.Objects.Logger |
class (GObject o, IsDescendantOf Logger o) => IsLogger o Source #
Instances
(GObject o, IsDescendantOf Logger o) => IsLogger o Source # | |
Defined in GI.Soup.Objects.Logger |
Methods
Click to display all available methods, including inherited ones
Methods
bindProperty, bindPropertyFull, forceFloating, freezeNotify, getv, isFloating, notify, notifyByPspec, ref, refSink, runDispose, stealData, stealQdata, thawNotify, unref, watchClosure.
Getters
getData, getMaxBodySize, getProperty, getQdata.
Setters
setData, setDataFull, setMaxBodySize, setPrinter, setProperty, setRequestFilter, setResponseFilter.
getMaxBodySize
:: (HasCallStack, MonadIO m, IsLogger a) | |
=> a |
|
-> m Int32 | Returns: the maximum body size, or -1 if unlimited |
Get the maximum body size for logger
.
new
:: (HasCallStack, MonadIO m) | |
=> LoggerLogLevel |
|
-> m Logger | Returns: a new |
Creates a new Logger
with the given debug level.
If you need finer control over what message parts are and aren't
logged, use [methodlogger
.set_request_filter] and
[methodlogger
.set_response_filter].
setMaxBodySize
:: (HasCallStack, MonadIO m, IsLogger a) | |
=> a |
|
-> Int32 |
|
-> m () |
Sets the maximum body size for logger
(-1 means no limit).
setPrinter
:: (HasCallStack, MonadIO m, IsLogger a) | |
=> a |
|
-> LoggerPrinter |
|
-> m () |
Sets up an alternate log printing routine, if you don't want
the log to go to stdout
.
setRequestFilter
loggerSetRequestFilter Source #
:: (HasCallStack, MonadIO m, IsLogger a) | |
=> a |
|
-> LoggerFilter |
|
-> m () |
Sets up a filter to determine the log level for a given request.
For each HTTP request logger
will invoke requestFilter
to
determine how much (if any) of that request to log. (If you do not
set a request filter, logger
will just always log requests at the
level passed to [ctorlogger
.new].)
setResponseFilter
loggerSetResponseFilter Source #
:: (HasCallStack, MonadIO m, IsLogger a) | |
=> a |
|
-> LoggerFilter |
|
-> m () |
Sets up a filter to determine the log level for a given response.
For each HTTP response logger
will invoke responseFilter
to
determine how much (if any) of that response to log. (If you do not
set a response filter, logger
will just always log responses at
the level passed to [ctorlogger
.new].)
Properties
level
The level of logging output.
constructLoggerLevel :: (IsLogger o, MonadIO m) => LoggerLogLevel -> m (GValueConstruct o) Source #
Construct a GValueConstruct
with valid value for the “level
” property. This is rarely needed directly, but it is used by new
.
getLoggerLevel :: (MonadIO m, IsLogger o) => o -> m LoggerLogLevel Source #
Get the value of the “level
” property.
When overloading is enabled, this is equivalent to
get
logger #level
setLoggerLevel :: (MonadIO m, IsLogger o) => o -> LoggerLogLevel -> m () Source #
Set the value of the “level
” property.
When overloading is enabled, this is equivalent to
set
logger [ #level:=
value ]
maxBodySize
If [propertylogger
:level] is LoggerLogLevelBody
, this gives
the maximum number of bytes of the body that will be logged.
(-1 means "no limit".)
constructLoggerMaxBodySize :: (IsLogger o, MonadIO m) => Int32 -> m (GValueConstruct o) Source #
Construct a GValueConstruct
with valid value for the “max-body-size
” property. This is rarely needed directly, but it is used by new
.
getLoggerMaxBodySize :: (MonadIO m, IsLogger o) => o -> m Int32 Source #
Get the value of the “max-body-size
” property.
When overloading is enabled, this is equivalent to
get
logger #maxBodySize
setLoggerMaxBodySize :: (MonadIO m, IsLogger o) => o -> Int32 -> m () Source #
Set the value of the “max-body-size
” property.
When overloading is enabled, this is equivalent to
set
logger [ #maxBodySize:=
value ]