@@ -178,6 +178,95 @@ be used for calls to formatting functions like `fmt.Errorf`,
178178But not for statements that are important for the flow or logic of the code,
179179like ` require.NoErrorf() ` .
180180
181+ #### Exceptions and additional styling for structured logging
182+
183+ When making use of structured logging calls (there are any ` btclog.Logger `
184+ methods ending in ` S ` ), a few different rules and exceptions apply.
185+
186+ 1 ) ** Static messages:** Structured log calls take a ` context.Context ` as a first
187+ parameter and a _ static_ string as the second parameter (the ` msg ` parameter).
188+ Formatted strings should ideally not be used for the construction of the ` msg `
189+ parameter. Instead, key-value pairs (or ` slog ` attributes) should be used to
190+ provide additional variables to the log line.
191+
192+ ** WRONG**
193+ ``` go
194+ log.DebugS (ctx, fmt.Sprintf (" User %d just spent %.8f to open a channel" , userID, 0.0154 ))
195+ ```
196+
197+ ** RIGHT**
198+ ``` go
199+ log.InfoS (ctx, " Channel open performed" ,
200+ slog.Int (" user_id" , userID),
201+ btclog.Fmt (" amount" , " %.8f " , 0.00154 ))
202+ ```
203+
204+ 2 ) ** Key-value attributes** : The third parameter in any structured log method is
205+ a variadic list of the ` any ` type but it is required that these are provided in
206+ key-value pairs such that an associated ` slog.Attr ` variable can be created for
207+ each key-value pair. The simplest way to specify this is to directly pass in the
208+ key-value pairs as raw literals as follows:
209+
210+ ``` go
211+ log.InfoS (ctx, " Channel open performed" , " user_id" , userID, " amount" , 0.00154 )
212+ ```
213+ This does work, but it becomes easy to make a mistake and accidentally leave out
214+ a value for each key provided leading to a nonsensical log line. To avoid this,
215+ it is suggested to make use of the various ` slog.Attr ` helper functions as
216+ follows:
217+
218+ ``` go
219+ log.InfoS (ctx, " Channel open performed" ,
220+ slog.Int (" user_id" , userID),
221+ btclog.Fmt (" amount" , " %.8f " , 0.00154 ))
222+ ```
223+
224+ 3 ) ** Line wrapping** : Structured log lines are an exception to the 80-character
225+ line wrapping rule. This is so that the key-value pairs can be easily read and
226+ reasoned about. If it is the case that there is only a single key-value pair
227+ and the entire log line is still less than 80 characters, it is acceptable to
228+ have the key-value pair on the same line as the log message. However, if there
229+ are multiple key-value pairs, it is suggested to use the one line per key-value
230+ pair format. Due to this suggestion, it is acceptable for any single key-value
231+ pair line to exceed 80 characters for the sake of readability.
232+
233+ ** WRONG**
234+ ``` go
235+ // Example 1.
236+ log.InfoS (ctx, " User connected" ,
237+ " user_id" , userID)
238+
239+ // Example 2.
240+ log.InfoS (ctx, " Channel open performed" , " user_id" , userID,
241+ btclog.Fmt (" amount" , " %.8f " , 0.00154 ), " channel_id" , channelID)
242+
243+ // Example 3.
244+ log.InfoS (ctx, " Bytes received" ,
245+ " user_id" , userID,
246+ btclog.Hex (" peer_id" , peerID.SerializeCompressed ()),
247+ btclog.Hex (" message" , []bytes{
248+ 0x01 , 0x02 , 0x03 , 0x04 , 0x05 , 0x06 , 0x07 , 0x08 ,
249+ })))
250+ ```
251+
252+ ** RIGHT**
253+ ``` go
254+ // Example 1.
255+ log.InfoS (ctx, " User connected" , " user_id" , userID)
256+
257+ // Example 2.
258+ log.InfoS (ctx, " Channel open performed" ,
259+ slog.Int (" user_id" , userID),
260+ btclog.Fmt (" amount" , " %.8f " , 0.00154 ),
261+ slog.String (" channel_id" , channelID))
262+
263+ // Example 3.
264+ log.InfoS (ctx, " Bytes received" ,
265+ " user_id" , userID,
266+ btclog.Hex (" peer_id" , peerID.SerializeCompressed ()),
267+ btclog.Hex (" message" , []bytes{0x01 , 0x02 , 0x03 , 0x04 , 0x05 , 0x06 , 0x07 , 0x08 })))
268+ ```
269+
181270### Wrapping long function definitions
182271
183272If one is forced to wrap lines of function arguments that exceed the
0 commit comments