You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: co-log-json/Readme.md
+35-35Lines changed: 35 additions & 35 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,14 +1,14 @@
1
1
# co-log-json
2
2
3
-
`co-log-json` allows to write structured logs in your application.
3
+
`co-log-json` allows writing structured logs in your application.
4
4
5
-
The library allows to add additional machinereadable context to the log
6
-
messages. I.e. each log message is a json object with a predefined structure
5
+
The library allows adding additional machine-readable context to the log
6
+
messages. I.e. each log message is a JSON object with a predefined structure
7
7
where additional user context can be added. Such logs can be easily indexed
8
-
by external logs systems such as [graylog](https://www.graylog.org) or
8
+
by external logs systems such as [Graylog](https://www.graylog.org) or
9
9
[Elastic search](https://www.elastic.co). The message logging is done using
10
-
a special context, that keeps information about additional attributes.
11
-
Such contexts forms a nested scope, and all messages in the score inherit provided
10
+
a special context, that keeps the information about additional attributes.
11
+
Such contexts form a nested scope, and all messages in the score inherit provided
12
12
context:
13
13
14
14
```
@@ -22,26 +22,26 @@ context:
22
22
```
23
23
24
24
25
-
In other words this library takes two choices:
25
+
In other words, this library takes two choices:
26
26
27
27
1. We write full context with each message.
28
-
This approach allows to use external tools (like elastic-search) that can index message
28
+
This approach allows using external tools (like elastic-search) that can index message
29
29
without any additional work and information.
30
-
Any message can be lost without affecting ability to decode other messages. Alternative
31
-
approach could be emitting a list of events (possibly as a bytecode), such approach
30
+
Any message can be lost without affecting the ability to decode other messages. An alternative
31
+
approach could be emitting a list of events (possibly as a bytecode), such an approach
32
32
is taken by the tracing libraries. It requires more works during reading and indexing
33
-
logs, and in case in some logs are logs may render later ones unusable or lose some info.
33
+
logs, and in the case in some logs are logs may render later ones unusable or lose some info.
34
34
35
35
2. We keep a state context so we don't need to attach context messages to each one.
36
-
Alternative approach is extraction of the structure information from the message itself.
36
+
An alternative approach is the extraction of the structure information from the message itself.
37
37
This approach is taken in some structured logging libraries, it can provide better error
38
-
messages. However it requires to think about the message context all the time (and developer
38
+
messages. However, it requires to think about the message context all the time (and developer
39
39
user may not even know all interesting context where the message will be used).
40
40
41
41
42
42
# Using a library
43
43
44
-
In order to use a library you'll need to add `co-log-json` to the dependency list.
44
+
To to use a library you'll need to add `co-log-json` to the dependency list.
45
45
46
46
```
47
47
library.cabal
@@ -63,8 +63,8 @@ import System.IO (stderr)
63
63
64
64
main::IO()
65
65
main =do
66
-
-- First we need to setup log storing function:
67
-
--In order to emit logs we need to create a context.
66
+
-- First, we need to set up log storing function:
67
+
--To emit logs we need to create a context.
68
68
-- Context takes the action to store log and it's possible to
69
69
-- attach additional information to it.
70
70
@@ -100,24 +100,24 @@ main = do
100
100
-- There are other helper functions list `logInfo`, `logNotice`, etc.
101
101
```
102
102
103
-
Now let's discuss `LogStr` type. It exists in order to efficiently generate message without
104
-
extra allocations that can be avoided. Basically it's just a [Text.Builder](http://hackage.haskell.org/package/text-1.2.4.0/docs/Data-Text-Lazy-Builder.html) though iternal
103
+
Now let's discuss `LogStr` type. It exists to efficiently generate message without
104
+
extra allocations that can be avoided. It's just a [Text.Builder](http://hackage.haskell.org/package/text-1.2.4.0/docs/Data-Text-Lazy-Builder.html) though internal
105
105
representation may evolve in the future. `LogStr` allows message concatenation without allocating
106
106
intermediate structures, so it allows efficient log building. For example line:
107
107
108
108
```haskell
109
109
logDebug context $"a"<>"b"<>"c"
110
110
```
111
111
112
-
will write all text string "a", "b", "c" directy to the buffer, and can actually do more optimizations.
113
-
So it's quite safe to use the librart even with a large amount of logs.
112
+
will write all text string "a", "b", "c" directly to the buffer, and can do more optimizations.
113
+
So it's quite safe to use the library even with a large number of logs.
114
114
115
115
The 'LogStr' type implement [IsString](http://hackage.haskell.org/package/base-4.14.0.0/docs/Data-String.html#t:IsString) instance it means that you can just write string literals
116
116
and they will be treated as 'LogStr'. To concatenate two 'LogStr' you can use [`<>`](https://hackage.haskell.org/package/base-4.14.0.0/docs/Data-Semigroup.html#t:Semigroup) operation.
117
117
118
118
In addition you can convert any string lines that has [StringConv a T.Text](https://hackage.haskell.org/package/string-conv-0.1.2/docs/Data-String-Conv.html), i.e. can be converted
119
119
to LogStr using `ls :: StringConv a T.Text => a -> LogStr`.
120
-
Efficiency and safety of this convertion depends on the concrete instance implementation and is out
120
+
Efficiency and safety of this conversion depends on the concrete instance implementation and is out
121
121
of control of the package.
122
122
123
123
```haskell
@@ -129,7 +129,7 @@ very general `showLS :: Show a => a -> LogStr` method that will work for any typ
129
129
130
130
## Adding context.
131
131
132
-
But just writing json messages is not very interesting, we want to control the context of the message.
132
+
But just writing JSON messages is not very interesting, we want to control the context of the message.
133
133
In order to add user data to the context we can use `addContext :: PushContext -> LoggerEnv -> LoggerEnv`
134
134
method.
135
135
@@ -164,9 +164,9 @@ Function `sl :: ToJSON a => T.Text -> a -> PushContext` prepares update to the c
164
164
It encodes user data to JSON. This is why we had to add type annotation to `1` otherwise GHC had
165
165
no means to infer the type).
166
166
167
-
It's important that library does not perform any compacation of key-values, i.e.:
167
+
It's important that the library does not perform any compaction of key-values, i.e.:
168
168
169
-
```
169
+
```haskell
170
170
logDebug (addContext (sl "user_id"2) context1) "Who am I?"
171
171
-- Will emit:
172
172
-- ```
@@ -183,25 +183,25 @@ the codebase the log belongs to. It's kept separate fom the data, and it's possi
183
183
use in library filtering (using [cfilter](https://kowainik.github.io/posts/2018-09-25-co-log#cfilter)) or filtering in external system.
184
184
185
185
186
-
The described functionality is enough to perform logging. However it may worth discussing
187
-
interporability with the rest of co-log ecosystem and ergonomics.
186
+
The described functionality is enough to perform logging. However, it may worth discussing
187
+
interoperability with the rest of co-log ecosystem and ergonomics.
188
188
189
-
## co-log interporability
189
+
## co-log interoperability
190
190
191
-
co-log ecosystem works with "LogAction m a" and in the package we use "LogEnv" it means
191
+
The co-log ecosystem works with "LogAction m a" and in the package, we use "LogEnv" it means
192
192
that we are losing most of the benefits of the library and can't use a lot of utility
193
-
functions. In order to improve the situation it's possible to convert LogEnv into
193
+
functions. To improve the situation it's possible to convert LogEnv into
194
194
`LogAction m (Severity,LogStr)` using function `unLogger`. Then we will have log action
195
-
that will emit a message with the current context, but context will no longer be modifiable.
195
+
that will emit a message with the current context, but the context will no longer be modifiable.
196
196
197
197
# Ergonomics
198
198
199
199
The package provides no ergonomic tools by default and it's important that `addContext` is a pure
200
-
function. On the one hand it introduces a log of boilerplate code but on the other.
200
+
function. On the one han,d it introduces a log of boilerplate code but on the other.
201
201
202
202
It allows to modify context even outside of the effectful computation for example with servant you may have:
0 commit comments