diff --git a/example/7-debug/README.md b/example/7-debug/README.md index a4457c7..eb9f563 100644 --- a/example/7-debug/README.md +++ b/example/7-debug/README.md @@ -82,9 +82,10 @@ As you can see, the report includes: The debugger is disabled by default to avoid leaking information by accident in a production environment. Whether the debugger is enabled or disabled, Dream -still writes error messages to the log — the debugger is only about also -sending them as *reponses*, which can be easier to work with, especially for -collaborators who are not currently looking at the log. +still writes error messages to the server-side log — the debugger is only +about also sending them to the client as *reponses*, which can be easier to +work with, especially for collaborators who are not currently looking at the +log.
@@ -101,8 +102,8 @@ Both the debugger's output and the non-debug error page are fully customizable - [**`8-error`**](../8-error/#files) handles all errors in one place, also customizing the debugger. -- [**`9-logging`**](../9=logging/#files) writes messages to the same Dream log - at various levels, and creates a sub-log. +- [**`9-log`**](../9-log/#files) writes messages to the same Dream log at + various levels, and creates a sub-log.
diff --git a/example/8-error/README.md b/example/8-error/README.md index 806046a..0dd18cc 100644 --- a/example/8-error/README.md +++ b/example/8-error/README.md @@ -85,8 +85,7 @@ to the point of intercepting strings generated by its HTTP dependencies. **Next steps:** -- [**`9-logging`**](../9-logging/#files) shows how to write messages to - Dream's log. +- [**`9-log`**](../9-log/#files) shows how to write messages to Dream's log. - [**`a-promise`**](../a-promise/#files) properly introduces Lwt, the promise library used by Dream. diff --git a/example/9-log/README.md b/example/9-log/README.md new file mode 100644 index 0000000..a94fcdf --- /dev/null +++ b/example/9-log/README.md @@ -0,0 +1,81 @@ +# `9-log` + +
+ +This app writes custom messages to Dream's log: + +```ocaml +let () = + Dream.run + @@ Dream.logger + @@ Dream.router [ + + Dream.get "/" + (fun request -> + Dream.log "Sending greeting to %s!" (Dream.client request); + Dream.respond "Good morning, world!"); + + Dream.get "/fail" + (fun _ -> + Dream.warning (fun log -> log "Raising an exception!"); + raise (Failure "The web app failed!")); + + ] + @@ Dream.not_found +``` + +
$ dune exec --root . ./log.exe
+ +
+ +If you visit [http://localhost:8080](http://localhost:8080) and then +[http://localhost:8080/fail](http://localhost:8080/fail), you will find these +messages in the log, between the other messages: + +``` +26.03.21 21:25:17.383 REQ 1 Sending greeting to 127.0.0.1:64099! +26.03.21 21:25:19.464 WARN REQ 2 Raising an exception! +``` + +As you can see, the functions take +[`Printf`-style format strings](https://caml.inria.fr/pub/docs/manual-ocaml/libref/Printf.html), +so you can quickly print values of various types to the log. + +
+ +`Dream.warning` is a bit strange. The reason it takes a callback, which waits +for a `log` argument, is because if the log threshold is higher than +`` `Warning``, the callback is never called, so the application doesn't spend +any time formatting a string that it will not print. This is the style of the +[Logs](https://erratique.ch/software/logs) library. Try inserting this code +right before `Dream.run` to see the message suppressed: + +```ocaml +Dream.initialize_log ~level:`Error (); +``` + +
+ +You can create named sub-logs for different parts of your application with +`Dream.sub_log`: + +```ocaml +let my_log = + Dream.sub_log "my.log" + +let () = + sub_log.warning (fun log -> log "Hmmm...") +``` + +
+ +**Next steps:** + +- [**`a-promise`**](../a-promise/#files) introduces Lwt, the promise library + used by Dream. +- [**`b-session`**](../b-session/#files) finally back to web development proper + — session management. + +
+ +[Up to the tutorial index](../#readme) diff --git a/example/9-log/dune b/example/9-log/dune new file mode 100644 index 0000000..6d0a528 --- /dev/null +++ b/example/9-log/dune @@ -0,0 +1,3 @@ +(executable + (name log) + (libraries dream)) diff --git a/example/9-log/dune-project b/example/9-log/dune-project new file mode 100644 index 0000000..929c696 --- /dev/null +++ b/example/9-log/dune-project @@ -0,0 +1 @@ +(lang dune 2.0) diff --git a/example/9-log/log.ml b/example/9-log/log.ml new file mode 100644 index 0000000..1c6c9f9 --- /dev/null +++ b/example/9-log/log.ml @@ -0,0 +1,17 @@ +let () = + Dream.run + @@ Dream.logger + @@ Dream.router [ + + Dream.get "/" + (fun request -> + Dream.log "Sending greeting to %s!" (Dream.client request); + Dream.respond "Good morning, world!"); + + Dream.get "/fail" + (fun _ -> + Dream.warning (fun log -> log "Raising an exception!"); + raise (Failure "The web app failed!")); + + ] + @@ Dream.not_found diff --git a/example/README.md b/example/README.md index 56ba920..70212a7 100644 --- a/example/README.md +++ b/example/README.md @@ -16,11 +16,13 @@ list below and jump to whatever interests you! - [**`5-echo`**](5-echo/#files)  —  reads request bodies. - [**`6-template`**](6-template/#files)  —  renders responses from templates and guards against XSS. -- [**`7-debug`**](7-debug)  —  includes detailed information +- [**`7-debug`**](7-debug/#files)  —  includes detailed + information about errors in responses. -- [**`8-error`**](8-error)  —  customize all error responses in - one place. -- [**`9-logging`**](9-logging) +- [**`8-error`**](8-error/#files)  —  customize all error + responses in one place. +- [**`9-log`**](9-log/#files)  —  writing messages to Dream's + log. - [**`a-promise`**](a-promise) - [**`b-session`**](a-session) - [**`c-cookie`**](b-cookie)