Skip to content

Commit 034c8b1

Browse files
serathiusehashman
andauthored
Update instruction for naming arguments (#5537)
* Update instruction for naming arguments * Apply suggestions from code review Co-authored-by: Elana Hashman <[email protected]> * Update contributors/devel/sig-instrumentation/migration-to-structured-logging.md Co-authored-by: Elana Hashman <[email protected]> * Update contributors/devel/sig-instrumentation/migration-to-structured-logging.md Co-authored-by: Elana Hashman <[email protected]> Co-authored-by: Marek Siarkowicz <[email protected]> Co-authored-by: Elana Hashman <[email protected]>
1 parent f0a10a6 commit 034c8b1

File tree

1 file changed

+79
-25
lines changed

1 file changed

+79
-25
lines changed

contributors/devel/sig-instrumentation/migration-to-structured-logging.md

Lines changed: 79 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,12 @@ has different meaning for variadic arguments. Instead of just passing arguments,
201201
argument name and argument value. This means when migrating a log call we need to add an additional string before each
202202
argument, that will be used as it's name.
203203

204+
How variable arguments should be used:
205+
206+
```go
207+
klog.InfoS("message", "key1", value1, "key2", "value2")
208+
```
209+
204210
For example
205211
```go
206212
func LogHTTP(r *http.Request) {
@@ -214,37 +220,85 @@ func LogHTTP(r *http.Request) {
214220
}
215221
```
216222

217-
Names of arguments should use [lowerCamelCase] and be alphanumeric. Arguments names in one log call should be unique.
218-
Names should be picked based on semantic meaning of value itself, not the context in which is used (log message should
219-
imply the context). For example names like `status` should be used over (`desiredStatus`, `oldStatus`, `badStatus`) thus
220-
allowing to query and join different log lines of the `status` field.
221-
222-
Kubernetes objects should be referenced using only their kind, no matter their api group or version. Example argument
223-
names: `deployment`, `pod`, `node`, `replicaSet`. For objects of unknown type, is ok to log them under `object` key with
224-
addition of `apiVersion` and `kind` fields describing the k8s object type.
225-
226-
In situations when we want to the log value of the same meaning twice (e.g. transition between state) it is ok to name
227-
an additional argument based on context, but leaving one most current/correct value with canonical name.
228-
229-
Examples of keys (strongly suggested, will be extended when pattern emerge, no standard schema yet):
230-
* `err` - error when using `klog.InfoS`. Used for expected errors that are not `klog.ErrorS`.
231-
* `object` - reference to k8s objects of unknown type. Should be used with `kind` and `apiVersion`.
232-
* `kind` - kind of k8s object of unknown type.
233-
* `apiVersion` - API version of k8s object of unknown type.
234-
235-
Example:
223+
When deciding on names of arguments you should:
224+
* Always use [lowerCamelCase], for example use `containerName` and not `container name` or `container_name`.
225+
* Use [alphanumeric] characters: no special characters like `%$*`, non-latin, or unicode characters.
226+
* Use object kind when referencing Kubernetes objects, for example `deployment`, `pod` and `node`.
227+
* Describe the type of value stored under the key and use normalized labels:
228+
* Don't include implementation-specific details in the labels. Don't use `directory`, do use `path`.
229+
* Do not provide additional context for how value is used. Don't use `podIP`, do use `IP`.
230+
* With the exception of acronyms like "IP" and the standard "err", don't shorten names. Don't use `addr`, do use `address`.
231+
* When names are very ambiguous, try to include context in the label. For example, instead of
232+
`key` use `cacheKey` or instead of `version` use `dockerVersion`.
233+
* Be consistent, for example when logging file path we should always use `path` and not switch between
234+
`hostPath`, `path`, `file`.
235+
236+
Here are a few exceptions to the rules above---some cases are temporary workarounds that may change if we settle on better solution:
237+
* Do use `err` rather than `error` to match the key used by `klog.ErrorS`
238+
* Context in name is acceptable to distinguish between values that normally go under same key. For example using both
239+
`status` and `oldStatus` in log that needs to show the change between statuses.
240+
* When Kubernetes object kind is unknown without runtime checking we should use `object` key. To provide information
241+
about kind we should add separate `apiVersion` and `kind` fields.
242+
* If we cannot use `klog.KObj` nor `klog.KRef` for Kubernetes object, like in cases when we only have access to name or UID,
243+
then we should fallback to using object kind with suffix based on value type. For example `podName`, `podUID`.
244+
* When providing multiple indistinguishable values (for example list of evicted pods), then we can use plural version of
245+
argument name. For example we should use `pods` and not `podList`.
246+
247+
Examples of **good keys** (strongly suggested, will be extended when pattern emerge, no standard schema yet):
248+
* `cacheKey`
249+
* `cacheValue`
250+
* `CIDR`
251+
* `containerID`
252+
* `containerName`
253+
* `controller`
254+
* `cronJob`
255+
* `deployment`
256+
* `dockerVersion`
257+
* `duration`
258+
* `err`
259+
* `job`
260+
* `object`
261+
* `pod`
262+
* `podName`
263+
* `podUID`
264+
* `PVC`
265+
* `PV`
266+
* `volumeName`
267+
* `replicaSet`
268+
269+
Examples of **bad** keys:
270+
* `addr` - replace with `address`
271+
* `container` - replace with `containerName` or `containerID` depending on value
272+
* `currentNode` - replace with `node`
273+
* `directory` - replace with `path`
274+
* `elapsed` - replace with `duration`
275+
* `externalIP` - replace with `IP`
276+
* `file` - replace with `path`
277+
* `hostPath` - replace with `path`
278+
* `ip` - replace with `IP`
279+
* `key` - replace with key describing what kind of key it is, for example `cacheKey`
280+
* `loadBalancerIP` - replace with `IP`
281+
* `podFullName` - try to rewrite code so that pod name or pod object can be used with `pod` or `podName` keys
282+
* `podIP` - replace with `IP`
283+
* `podList` - replace with `pods`
284+
* `version` - replace with key describing what it belongs to so that it can be compared, for example `dockerVersion`
285+
* `servicePortName` - replace with `portName`
286+
* `svc` - replace with `service`
287+
288+
Example of using context in to distinguish between two same keys:
236289

237290
```go
238-
func ChangeStatus(newStatus, currentStatus string) {
239-
err := changeStatus(newStatus)
240-
if err != nil {
241-
klog.ErrorS(err, "Failed changing status", "desiredStatus", newStatus, "status", currentStatus)
242-
}
243-
klog.InfoS("Changed status", "previousStatus", currentStatus, "status", newStatus)
291+
func ChangePodStatus(newStatus, currentStatus string) {
292+
klog.InfoS("PodStatusController found pod with status", "status", currentStatus)
293+
...
294+
// Logic that changes status
295+
...
296+
klog.InfoS("PodStatusController changed pod status", "oldStatus", currentStatus, "status", newStatus)
244297
}
245298
```
246299

247300
[lowerCamelCase]: https://en.wiktionary.org/wiki/lowerCamelCase
301+
[alphanumeric]: https://en.wikipedia.org/wiki/Alphanumeric
248302

249303
### Use `klog.KObj` and `klog.KRef` for Kubernetes objects
250304

0 commit comments

Comments
 (0)