Skip to content

Commit

Permalink
feat: statefulset logging
Browse files Browse the repository at this point in the history
  • Loading branch information
tobifroe committed Jul 27, 2024
1 parent 7890e62 commit 46a0e94
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 9 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 12 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,17 @@
klog is a tool that allows you to tail logs of multiple Kubernetes pods simultaneously.

## Installation
TBD.

You can build and install klog using cargo:
```bash
# Using Cargo
cargo install klog
```
alternatively, grab a pre-built binary for your OS from the [releases page](https://github.com/tobifroe/klog/releases).
Curently, there are x86_64 binaries provided for Windows, MacOS and Linux.


## Usage
klog will use your current sessions kubecontext.

```bash
klog [OPTIONS] --namespace <NAMESPACE> --pods <PODS>...
Expand All @@ -24,18 +27,19 @@ klog -n my-namespace -p pod1 pod2 pod3 -f
### Options

```
-n, --namespace <NAMESPACE> Namespace to use
-p, --pods <PODS>... Pods to log
-d, --deployment <DEPLOYMENTS>... Deployments to log
-f, --follow Follow log?
-n, --namespace <NAMESPACE> Namespace to use
-p, --pods <PODS>... Pods to log
-d, --deployments <DEPLOYMENTS>... Deployments to log
-s, --statefulsets <STATEFULSETS>... Statefulsets to log
-f, --follow Follow log?
```

## Example

To tail logs from pods `pod1`, `pod2`, and `pod3` in the `my-namespace` namespace and follow the logs, run:
To tail logs from pods `pod1`, `pod2`, `pod3` and deployment `my-service` in the `my-namespace` namespace and follow the logs, run:

```bash
klog -n my-namespace -p pod1 pod2 pod3 --follow
klog -n my-namespace -p pod1 pod2 pod3 -d my-service --follow
```

## Acknowledgements
Expand Down
29 changes: 29 additions & 0 deletions src/k8s.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use colored::Colorize;
use futures_util::AsyncBufReadExt;
use futures_util::TryStreamExt;
use k8s_openapi::api::apps::v1::Deployment;
use k8s_openapi::api::apps::v1::StatefulSet;
use k8s_openapi::api::core::v1::Pod;
use kube::api::{Api, ListParams, LogParams};
use kube::runtime::reflector::Lookup;
Expand Down Expand Up @@ -40,6 +41,34 @@ pub async fn get_pod_list_for_deployment(
Ok(pod_name_list)
}

pub async fn get_pod_list_for_statefulset(
client: &kube::Client,
statefulset_name: &str,
ns_name: &str,
) -> Result<Vec<String>, anyhow::Error> {
let statefulset_api: Api<StatefulSet> = Api::namespaced(client.clone(), ns_name);
let statefulset = statefulset_api.get(statefulset_name).await?;

let spec = statefulset.spec.unwrap();
let match_labels = spec.selector.match_labels.unwrap();

let labels: String = match_labels
.iter()
.map(|(key, value)| format!("{}={}", key, value))
.join(",");

let pod_api: Api<Pod> = Api::namespaced(client.clone(), ns_name);
let list_params = ListParams::default().labels(&labels);
let pod_list = pod_api.list(&list_params).await?;

let mut pod_name_list: std::vec::Vec<std::string::String> = vec![];
for pod in pod_list.iter() {
pod_name_list.push(pod.name().unwrap().to_string());
}

Ok(pod_name_list)
}

pub async fn stream_single_pod_logs(
client: &kube::Client,
pod_name: &str,
Expand Down
13 changes: 13 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ struct Args {
#[arg(short, long, value_delimiter = ' ', num_args = 1..)]
deployments: Vec<String>,

/// Statefulsets to log
#[arg(short, long, value_delimiter = ' ', num_args = 1..)]
statefulsets: Vec<String>,

/// Pods to log
#[arg(short, long, value_delimiter = ' ', num_args = 1..)]
pods: Vec<String>,
Expand All @@ -41,6 +45,15 @@ async fn main() -> anyhow::Result<()> {
}
}

if !args.statefulsets.is_empty() {
for statefulset in args.statefulsets.iter() {
pod_list.append(
&mut k8s::get_pod_list_for_statefulset(&client, statefulset, &args.namespace)
.await?,
);
}
}

let namespace = args.namespace;
let follow = args.follow;

Expand Down
23 changes: 23 additions & 0 deletions statefulset.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web
spec:
selector:
matchLabels:
app: nginx # has to match .spec.template.metadata.labels
serviceName: "nginx"
replicas: 3 # by default is 1
minReadySeconds: 10 # by default is 0
template:
metadata:
labels:
app: nginx # has to match .spec.selector.matchLabels
spec:
terminationGracePeriodSeconds: 10
containers:
- name: nginx
image: registry.k8s.io/nginx-slim:0.24
ports:
- containerPort: 80
name: web

0 comments on commit 46a0e94

Please sign in to comment.