-
Notifications
You must be signed in to change notification settings - Fork 109
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add --condition
#276
base: master
Are you sure you want to change the base?
Add --condition
#276
Conversation
I'm giving #213 a go because I really need it. But I'm struggling with the second TODO. Is there a chance someone can help me? PS: code is not yet ready for final review, but it's working. Also, I have almost zero experience with Golang. |
--condition
I will look into it this weekend. |
Thanks a lot @superbrothers! |
It is on the way, but I have a working patch. I won't have much time this weekend but will be able to work on it after that. 816c896 You can try it out as soon as you build it. |
@superbrothers, thanks a lot, you are the best! However, it's not working quite as I expected. Let me help build a testing scenario too: kubectl apply -f - <<'EOF'
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: test
spec:
replicas: 1
selector:
matchLabels:
app: test
serviceName: test
template:
metadata:
labels:
app: test
spec:
terminationGracePeriodSeconds: 1
containers:
- name: test
image: bash
command:
- bash
- -c
- |
count=0
while true; do
echo "Hello World: $count"
count=$((count+1))
if [[ $count -eq 10 ]]; then
touch /tmp/healthy
fi
sleep 1
done
readinessProbe:
exec:
command:
- cat
- /tmp/healthy
initialDelaySeconds: 10
periodSeconds: 1
EOF This pod becomes ready in about 11 seconds. Start the stern process with: ./dist/stern '.*' --condition ready=false --tail 0 Stern correctly filters out the pod if the pod is already ready, but Stern does not stop tailing the logs when the pod becomes ready: WindowsTerminal_lMhjxZZGe5.mp4 |
Ok, I think I know what's going on: K8s does not seem to emit an event for when the pod becomes ready. I'm investigating what can be done about it. |
Checking I wonder if and how we could do something similar: If the pod initially matches condition and gets (I already tried to tinker with it myself without much success) |
Hi, It appears that Stern has detected the events, but they could be filtered out by targetFilter.shouldAdd(). The following patch may resolve the issue, but I've noticed the behavior of diff --git a/stern/stern.go b/stern/stern.go
index c492519..dcece50 100644
--- a/stern/stern.go
+++ b/stern/stern.go
@@ -222,7 +222,7 @@ func Run(ctx context.Context, config *Config) error {
if !ok {
continue
}
- cancel.(func())()
+ cancel.(context.CancelFunc)()
case <-nctx.Done():
return nil
}
diff --git a/stern/target.go b/stern/target.go
index 553e8c2..cbc6788 100644
--- a/stern/target.go
+++ b/stern/target.go
@@ -136,8 +136,14 @@ OUTER:
Container: c.Name,
}
+ if !conditionFound {
+ visitor(t, false)
+ f.forget(string(pod.UID))
+ continue
+ }
+
if f.shouldAdd(t, string(pod.UID), c) {
- visitor(t, conditionFound)
+ visitor(t, true)
}
}
} The demo below illustrates that the logs restart when the pod is deleted (at 00:18). |
Wow, it looks to be working indeed as per your demo. Can't wait to try your patch out. BTW the behavior you described is indeed misleading. That would not happen though when using --tail=0, which is my use case (only capture live logs, not past logs). I will think about what can be done to circumvent this. Maybe Stern has to remember up until which point it tailed logs for a given pod, and when it starts tailing it again, it should tail from that point on. |
@felipecrs Oh, sorry. I missed the As you mentioned, Stern behaves as expected when using I believe it would be better to automatically set |
@tksm really amazing, indeed it works like a charm. I added both @superbrothers' commit and your patch to this PR now. Something I believe I need to do before merging is to fix the condition syntax for the config file. I left it as a string there, which makes it exactly as the CLI, but perhaps I should convert it to an object like: - condition: ready=false
+ condition:
+ name: ready
+ value: false What do you think? Personally, I don't mind. Even the first one looks good to me. Another thing to think about is the concern raised by @tksm above when not using |
Co-authored-by: Takashi Kusumi <[email protected]>
I'm glad to hear it worked as expected. 🎉 Config fileI believe that the first one ( --tail=0 optionFor the initial implementation, I think that the caveat in README.md and the error message when # Raise an error when `--tail=0` is not set
$ ./dist/stern '.*' --condition ready=false
Error: Currently, --condition and --no-follow=false only work with --tail=0
Usage:
stern pod-query [flags] diff --git a/cmd/cmd.go b/cmd/cmd.go
index 35e3060..2c70027 100644
--- a/cmd/cmd.go
+++ b/cmd/cmd.go
@@ -130,6 +130,9 @@ func (o *options) Validate() error {
if o.selector != "" && o.resource != "" {
return errors.New("--selector and the <resource>/<name> query can not be set at the same time")
}
+ if o.condition != "" && !o.noFollow && o.tail != 0 {
+ return errors.New("Currently, --condition and --no-follow=false only work with --tail=0")
+ }
return nil
} |
I'm sorry @tksm, but why enforce I changed it in the commit. |
I also just realized that For example, with apiVersion: batch/v1
kind: Job
metadata:
name: test-two
spec:
completions: 1
template:
metadata:
labels:
app: test-two
spec:
terminationGracePeriodSeconds: 1
restartPolicy: OnFailure
containers:
- name: test-two
image: bash
command:
- bash
- -c
- |
count=0
while true; do
echo "World Hello: $count"
count=$((count+1))
if [[ $count -eq 10 ]]; then
exit 1
fi
sleep 1
done Similarly, for a pod which does not have a readinessProbe: apiVersion: apps/v1
kind: StatefulSet
metadata:
name: test-two
spec:
replicas: 1
selector:
matchLabels:
app: test-two
serviceName: test-two
template:
metadata:
labels:
app: test-two
spec:
terminationGracePeriodSeconds: 1
containers:
- name: test-two
image: bash
command:
- bash
- -c
- |
count=0
while true; do
echo "World Hello: $count"
count=$((count+1))
if [[ $count -eq 10 ]]; then
exit 0
fi
sleep 1
done My use case (#213) was to filter out only healthy pods, and simple conditions like that cannot fulfil my needs. The only solution I thought to circumvent this is:
Feedback is appreciated. |
Co-authored-by: Takashi Kusumi <[email protected]>
Another thing, @tksm, I think allowing people to specify I want to only display logs for pods which are not ready, but displaying their last 3 lines before they became unhealthy. |
Ok, now it fulfils my use case:
Please let me know what you think about it. And, as always, thanks for the help. |
Ok, I have been soaking this internally during the day and the results are really good for my use case. I would like to ask the maintainers to give me the go ahead on the current solution ( |
@felipecrs Let me clarify the conditions under which you want to view pod logs in your use case. I assume you do NOT want to view logs when:
Please inform me if there are any additional conditions. In that case, I believe specifying these conditions using flags might be overly complex. I came up with another approach with It may be possible to address this use case using the Although templates can be complex, this approach offers the flexibility to handle a wide range of use cases. You can use
|
Isn't that a very costly operation? Checking the pod per log line as opposed to only per event? |
But yes, this set of conditions satisfies my use case, which can be described in high level with something like: I want Stern to tail logs from all pods which are not healthy. If the pod does not have a health checker (readiness probe), then I want to tail its logs since I can't tell whether it's healthy or not. Precisely, I want to run Stern as a side car process to my helm upgrade command within my CI/CD pipeline, and these conditions allows for tracking the helm installation as it happens more decently than just showing all pod logs no matter what. In my use case, I have something around 50 pods to tail, but I install them incrementally (one helm chart per time). Filtering out pods which are healthy ensures I'm not showing logs for pods which were installed by previous helm installations. That said, I believe more people could leverage the same approach. If you really believe we should not be too narrow in the implementation, maybe we can invent some kind of --condition-template, which allows to run a template that should result in a "false" or "true" to decide whether the pod should be tailed or not. And in that case, I believe not even the helper podIsReady function needs to exist, as it can be easily implemented in the template itself. |
Thanks for your detailed explanation! I understand the use case, and it sounds worth implementing. @superbrothers What do you think? I prefer creating a dedicated flag for this use case to improve clarity, but I find the term |
I don't mind going the |
btw, I wrote a small tool to check all conditions in a cluster: https://github.com/guettli/check-conditions PRs are welcome. |
Usage:
stern . --condition=ready=false
TODOs:
Fixes #213