@@ -178,17 +178,21 @@ retrieve certain log stream of a container, so it is great to implement this lon
178
178
179
179
### Non-Goals
180
180
181
- <!--
182
- What is out of scope for this KEP? Listing non-goals helps to focus discussion
183
- and make progress.
184
- -->
181
+ - Supporting the combination of a specific ` Stream ` (stdout or stderr) and ` TailLines ` in the first iteration. However,
182
+ if ` Stream ` is set to ` all ` , both ` Stream ` and ` TailLines ` can be specified together.
183
+ - Implementing a new log format
185
184
186
185
## Proposal
187
186
188
187
Add a new field ` Stream ` to ` PodLogOptions ` to allow users to indicate which log stream
189
188
they want to retrieve. To maintain backward compatibility, if this field is not set,
190
189
the combined stdout and stderr from the container will be returned to users.
191
190
191
+ Users are enabled to fetch the stderr log stream of a given container using kubectl as following:
192
+ ``` bash
193
+ kubectl logs --stream=stderr -c container pod
194
+ ```
195
+
192
196
### User Stories
193
197
194
198
Bob runs a service "foo" that continuously prints informational messages to stdout,
@@ -201,12 +205,53 @@ This problem could be resolved if Bob is able to specify that he only wants stde
201
205
202
206
### Notes/Constraints/Caveats (Optional)
203
207
204
- <!--
205
- What are the caveats to the proposal?
206
- What are some important details that didn't come across above?
207
- Go in to as much detail as necessary here.
208
- This might be a good place to talk about core concepts and how they relate.
209
- -->
208
+ It can be tricky when ` Stream ` and ` TailLines ` of ` PodLogOptions ` are both specified.
209
+
210
+ For instance, users might want to fetch the last 10 lines of the stderr log stream for a container, but
211
+ this is prohibitively expensive to implement from kubelet's perspective:
212
+
213
+ At present, container's logs are stored in an encoded format, either "json-file" or "cri" format:
214
+
215
+ ```
216
+ # json-file
217
+ {"log":"out1\n","stream":"stdout","time":"2024-08-20T09:31:37.985370552Z"}
218
+ {"log":"err1\n","stream":"stderr","time":"2024-08-20T09:31:37.985370552Z"}
219
+
220
+ # cri
221
+ 2016-10-06T00:17:09.669794202Z stdout F out1
222
+ 2016-10-06T00:17:09.669794202Z stderr F err1
223
+ ```
224
+
225
+ Please note that the log stream is encoded in each log line. Let's see what will happen if kubelet needs to return
226
+ the last 10 lines of the stderr log stream:
227
+ 1 . Kubelet has to decode each line of the log file from the bottom to determine whether it is from the stderr stream or not,
228
+ which is a CPU-intensive operation in practice.
229
+ 2 . What's worse, once kubelet identifies that a line is from the stderr stream, it must keep track of the matched lines
230
+ until a specified number of lines are found. This can be time-consuming, especially when only few lines of stderr logs
231
+ amidst a large number of stdout logs.
232
+
233
+ In conclusion, it is not practical for kubelet to return the last N lines of a specific log stream.
234
+
235
+ Alternatively, kubelet could return logs that match the given stream within the last N lines. For example, consider the following logs:
236
+ ```
237
+ {"log":"out1\n","stream":"stdout","time":"2024-08-20T09:31:37.985370552Z"}
238
+ {"log":"err1\n","stream":"stderr","time":"2024-08-20T09:31:37.985370552Z"}
239
+ {"log":"out2\n","stream":"stdout","time":"2024-08-20T09:31:37.985370552Z"}
240
+ {"log":"err2\n","stream":"stderr","time":"2024-08-20T09:31:37.985370552Z"}
241
+ ```
242
+
243
+ If users run ` kubectl logs --stream=stderr --tail=2 pod ` , kubelet would only return the following:
244
+ ```
245
+ err2
246
+ ```
247
+
248
+ This approach is more efficient, as kubelet only needs to parse a deterministic number of log lines once,
249
+ rather than potentially all of them. However, this may go against users' expectations and could lead to confusion.
250
+
251
+ Taking all these considerations into account, I propose that we do not support the combination of specific ` Stream `
252
+ and ` TailLines ` in the first iteration.
253
+ Additionally, the apiserver should validate the ` PodLogOptions ` to ensure that a specific ` Stream ` and ` TailLines `
254
+ are mutually exclusive.
210
255
211
256
### Risks and Mitigations
212
257
0 commit comments