-
Notifications
You must be signed in to change notification settings - Fork 84
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Issue/62 custom access and error log handlers (against master) #72
Changes from all commits
fb438cc
b3be5db
e28ec29
6b01854
8fe340f
8c4515f
b5e2305
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -23,12 +23,17 @@ module Snap.Internal.Http.Server.Config | |
, optDescrs | ||
, fmapOpt | ||
|
||
, AccessLogHandler | ||
, ErrorLogHandler | ||
|
||
, getAccessLog | ||
, getAccessLogHandler | ||
, getBind | ||
, getCompression | ||
, getDefaultTimeout | ||
, getErrorHandler | ||
, getErrorLog | ||
, getErrorLogHandler | ||
, getHostname | ||
, getLocale | ||
, getOther | ||
|
@@ -43,11 +48,13 @@ module Snap.Internal.Http.Server.Config | |
, getStartupHook | ||
|
||
, setAccessLog | ||
, setAccessLogHandler | ||
, setBind | ||
, setCompression | ||
, setDefaultTimeout | ||
, setErrorHandler | ||
, setErrorLog | ||
, setErrorLogHandler | ||
, setHostname | ||
, setLocale | ||
, setOther | ||
|
@@ -90,6 +97,7 @@ import Data.Typeable.Internal (Typeable, mkTyCon3) | |
#else | ||
import Data.Typeable (mkTyCon3) | ||
#endif | ||
import Data.Word (Word64) | ||
import Network (Socket) | ||
#if !MIN_VERSION_base(4,6,0) | ||
import Prelude hiding (catch) | ||
|
@@ -106,7 +114,7 @@ import System.IO (hPutStrLn, stderr) | |
import Data.ByteString.Builder (Builder, byteString, stringUtf8, toLazyByteString) | ||
import qualified System.IO.Streams as Streams | ||
------------------------------------------------------------------------------ | ||
import Snap.Core (MonadSnap, Request (rqClientAddr, rqClientPort), emptyResponse, finishWith, getRequest, logError, setContentLength, setContentType, setResponseBody, setResponseStatus) | ||
import Snap.Core (MonadSnap, Request (rqClientAddr, rqClientPort), Response, emptyResponse, finishWith, getRequest, logError, setContentLength, setContentType, setResponseBody, setResponseStatus) | ||
import Snap.Internal.Debug (debug) | ||
|
||
|
||
|
@@ -130,6 +138,15 @@ instance Show ConfigLog where | |
show (ConfigFileLog f) = "log to file " ++ show f | ||
show (ConfigIoLog _) = "custom logging handler" | ||
|
||
------------------------------------------------------------------------------ | ||
-- | This handler may be used (in conjunction with setErrorLogHandler) to write out error logs in a | ||
-- custom manner. | ||
type ErrorLogHandler = ByteString -> IO ByteString | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Wow, it deleted my previous changes here when I updated the PR. Not used to that. I do most of my work on BitBucket. So, what did you mean specifically about this type? Did you want me to:
I am just not sure what your previous comment here was asking for. Cheers. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I just meant that we already have this type in .Types without an alias (search for _logAccess in that file), so we should move the alias into .Types and use it there. BTW why is the type of ErrorLogHandler ByteString -> IO ByteString here? We use "Builder -> IO ()" internally in the server, and we should probably do the same here. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @gregorycollins So you want me to change the type to Builder -> IO Builder? Because otherwise the ErrorLogHandler would actually have to write the logs to the ConfigLog, rather than just producing logs in a custom format as it currently does. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, the error log handler should write the logs itself and return Let's say for example that (and this is a bad idea, but just for the sake of argument) you'd like to log the access log information into an SQL database. In this case, the solution you're providing is awkward, because we serialize to string without really needing to do that. In this case it's because the API we provide the user right now is bad --- the Ideally 0.10 and 1.0 should have the same API here, so that we introduce this feature once and we don't have to break user code in the upgrade from 0.10 to 1.0. In this case I'm totally OK with breaking users |
||
|
||
------------------------------------------------------------------------------ | ||
-- | This handler may be used (in conjunction with setAccessLogHandler) to write out access logs in a | ||
-- custom manner. | ||
type AccessLogHandler = Request -> Response -> Word64 -> IO ByteString | ||
|
||
------------------------------------------------------------------------------ | ||
-- We should be using ServerConfig here. There needs to be a clearer | ||
|
@@ -188,24 +205,26 @@ instance Show ConfigLog where | |
-- Any fields which are unspecified in the 'Config' passed to 'httpServe' (and | ||
-- this is the norm) are filled in with default values from 'defaultConfig'. | ||
data Config m a = Config | ||
{ hostname :: Maybe ByteString | ||
, accessLog :: Maybe ConfigLog | ||
, errorLog :: Maybe ConfigLog | ||
, locale :: Maybe String | ||
, port :: Maybe Int | ||
, bind :: Maybe ByteString | ||
, sslport :: Maybe Int | ||
, sslbind :: Maybe ByteString | ||
, sslcert :: Maybe FilePath | ||
, sslchaincert :: Maybe Bool | ||
, sslkey :: Maybe FilePath | ||
, compression :: Maybe Bool | ||
, verbose :: Maybe Bool | ||
, errorHandler :: Maybe (SomeException -> m ()) | ||
, defaultTimeout :: Maybe Int | ||
, other :: Maybe a | ||
, proxyType :: Maybe ProxyType | ||
, startupHook :: Maybe (StartupInfo m a -> IO ()) | ||
{ hostname :: Maybe ByteString | ||
, accessLog :: Maybe ConfigLog | ||
, errorLog :: Maybe ConfigLog | ||
, accessLogHandler :: Maybe AccessLogHandler | ||
, errorLogHandler :: Maybe ErrorLogHandler | ||
, locale :: Maybe String | ||
, port :: Maybe Int | ||
, bind :: Maybe ByteString | ||
, sslport :: Maybe Int | ||
, sslbind :: Maybe ByteString | ||
, sslcert :: Maybe FilePath | ||
, sslchaincert :: Maybe Bool | ||
, sslkey :: Maybe FilePath | ||
, compression :: Maybe Bool | ||
, verbose :: Maybe Bool | ||
, errorHandler :: Maybe (SomeException -> m ()) | ||
, defaultTimeout :: Maybe Int | ||
, other :: Maybe a | ||
, proxyType :: Maybe ProxyType | ||
, startupHook :: Maybe (StartupInfo m a -> IO ()) | ||
} | ||
#if MIN_VERSION_base(4,7,0) | ||
deriving Typeable | ||
|
@@ -273,6 +292,8 @@ instance Monoid (Config m a) where | |
{ hostname = Nothing | ||
, accessLog = Nothing | ||
, errorLog = Nothing | ||
, accessLogHandler = Nothing | ||
, errorLogHandler = Nothing | ||
, locale = Nothing | ||
, port = Nothing | ||
, bind = Nothing | ||
|
@@ -294,6 +315,8 @@ instance Monoid (Config m a) where | |
{ hostname = ov hostname | ||
, accessLog = ov accessLog | ||
, errorLog = ov errorLog | ||
, accessLogHandler = ov accessLogHandler | ||
, errorLogHandler = ov errorLogHandler | ||
, locale = ov locale | ||
, port = ov port | ||
, bind = ov bind | ||
|
@@ -346,10 +369,18 @@ getHostname = hostname | |
getAccessLog :: Config m a -> Maybe ConfigLog | ||
getAccessLog = accessLog | ||
|
||
-- | Get the access log handler | ||
getAccessLogHandler :: Config m a -> Maybe AccessLogHandler | ||
getAccessLogHandler = accessLogHandler | ||
|
||
-- | Path to the error log | ||
getErrorLog :: Config m a -> Maybe ConfigLog | ||
getErrorLog = errorLog | ||
|
||
-- | Get the error log handler | ||
getErrorLogHandler :: Config m a -> Maybe ErrorLogHandler | ||
getErrorLogHandler = errorLogHandler | ||
|
||
-- | Gets the locale to use. Locales are used on Unix only, to set the | ||
-- @LANG@\/@LC_ALL@\/etc. environment variable. For instance if you set the | ||
-- locale to \"@en_US@\", we'll set the relevant environment variables to | ||
|
@@ -421,9 +452,15 @@ setHostname x c = c { hostname = Just x } | |
setAccessLog :: ConfigLog -> Config m a -> Config m a | ||
setAccessLog x c = c { accessLog = Just x } | ||
|
||
setAccessLogHandler :: AccessLogHandler -> Config m a -> Config m a | ||
setAccessLogHandler x c = c { accessLogHandler = Just x } | ||
|
||
setErrorLog :: ConfigLog -> Config m a -> Config m a | ||
setErrorLog x c = c { errorLog = Just x } | ||
|
||
setErrorLogHandler :: ErrorLogHandler -> Config m a -> Config m a | ||
setErrorLogHandler x c = c { errorLogHandler = Just x } | ||
|
||
setLocale :: String -> Config m a -> Config m a | ||
setLocale x c = c { locale = Just x } | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Move this into ".Types" (see the _accessLog member, we are already using this type without an alias there)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've just tried to work out what you meant by this comment and I can't work it out. :( I think you mean: remove the ErrorLogHandler definition and just use ByteString -> IO ByteString directly all around the code?
But part of me is thinking that maybe you want me to move these type definitions to: src/Snap/Internal/Http/Server/Types.hs
I'm just confused because the only thing that _accessLog does that is similar to this is the ConfigIoLog constructor.
So maybe what you really want me to do is:
Is that more like what you meant? Which one is it? Or am I totally off the mark?