Skip to content

Commit

Permalink
Use new logs api
Browse files Browse the repository at this point in the history
  • Loading branch information
tarrencev committed Oct 18, 2023
1 parent c5f3ef1 commit 77e406d
Show file tree
Hide file tree
Showing 6 changed files with 149 additions and 49 deletions.
25 changes: 25 additions & 0 deletions Cargo.lock

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

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ edition = "2021"
anyhow = "1.0.75"
axum = "0.6"
clap = { version = "4.2", features = ["derive"] }
chrono = "0.4.31"
ctrlc = "3.4.1"
dirs = "5"
env_logger = "0.10"
graphql_client = "0.13.0"
Expand Down
32 changes: 14 additions & 18 deletions schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -11727,10 +11727,10 @@
{
"defaultValue": null,
"description": null,
"name": "cursor",
"name": "since",
"type": {
"kind": "SCALAR",
"name": "String",
"name": "Time",
"ofType": null
}
},
Expand Down Expand Up @@ -18092,22 +18092,14 @@
"deprecationReason": null,
"description": null,
"isDeprecated": false,
"name": "entries",
"name": "content",
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "LIST",
"name": null,
"ofType": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "String",
"ofType": null
}
}
"kind": "SCALAR",
"name": "String",
"ofType": null
}
}
},
Expand All @@ -18116,11 +18108,15 @@
"deprecationReason": null,
"description": null,
"isDeprecated": false,
"name": "nextCursor",
"name": "until",
"type": {
"kind": "SCALAR",
"name": "String",
"ofType": null
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "Time",
"ofType": null
}
}
}
],
Expand Down
13 changes: 12 additions & 1 deletion src/command/deployments/create.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@ use crate::{
},
};

use super::services::CreateCommands;
use super::{
logs::LogReader,
services::{CreateCommands, Service},
};

type Long = u64;

Expand Down Expand Up @@ -118,6 +121,14 @@ impl CreateArgs {
}
}

let service = match &self.create_commands {
CreateCommands::Katana(_) => Service::Katana,
CreateCommands::Torii(_) => Service::Torii,
};

let reader = LogReader::new(service, self.project.clone());
reader.stream(None).await?;

Ok(())
}
}
18 changes: 10 additions & 8 deletions src/command/deployments/logs.graphql
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
query DeploymentLogs($project: String!, $service: DeploymentService!, $cursor: String!, $limit: Int!) {
deployment(
name: $project
service: $service
) {
logs(cursor: $cursor, limit: $limit) {
entries
nextCursor
query DeploymentLogs(
$project: String!
$service: DeploymentService!
$since: Time
$limit: Int
) {
deployment(name: $project, service: $service) {
logs(since: $since, limit: $limit) {
content
until
}
}
}
108 changes: 86 additions & 22 deletions src/command/deployments/logs.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,19 @@
use std::{
sync::{
atomic::{AtomicBool, Ordering},
Arc,
},
time::Duration,
};

use anyhow::Result;
use clap::Args;
use graphql_client::{GraphQLQuery, Response};
use tokio::time::sleep;

use crate::{api::ApiClient, command::deployments::logs::deployment_logs::DeploymentService};

use crate::api::ApiClient;
use self::deployment_logs::{ResponseData, Variables};

use super::services::Service;

Expand All @@ -14,6 +25,8 @@ use super::services::Service;
)]
pub struct DeploymentLogs;

type Time = String;

#[derive(Debug, Args)]
#[command(next_help_heading = "Deployment logs options")]
pub struct LogsArgs {
Expand All @@ -23,44 +36,95 @@ pub struct LogsArgs {
#[arg(help = "The name of the deployment service.")]
pub service: Service,

#[arg(short, long = "since")]
#[arg(help = "Display logs after this RFC3339 timestamp.")]
pub since: Option<String>,

#[arg(short, long = "limit", default_value = "25")]
#[arg(help = "Display only the most recent `n` lines of logs.")]
pub limit: i64,

#[arg(short, long = "follow", default_value = "false")]
#[arg(help = "Stream service logs.")]
pub follow: bool,
}

impl LogsArgs {
pub async fn run(&self) -> Result<()> {
let service = match &self.service {
Service::Katana => deployment_logs::DeploymentService::katana,
Service::Torii => deployment_logs::DeploymentService::torii,
let reader = LogReader::new(self.service.clone(), self.project.clone());

if self.follow {
reader.stream(self.since.clone()).await?;
} else {
reader.query(self.since.clone(), self.limit).await?;
}

Ok(())
}
}

pub struct LogReader {
client: ApiClient,
service: Service,
project: String,
}

impl LogReader {
pub fn new(service: Service, project: String) -> Self {
LogReader {
client: ApiClient::new(),
service,
project,
}
}

pub async fn query(&self, since: Option<String>, limit: i64) -> Result<String> {
let service = match self.service {
Service::Katana => DeploymentService::katana,
Service::Torii => DeploymentService::torii,
};
let request_body = DeploymentLogs::build_query(deployment_logs::Variables {

let request_body = DeploymentLogs::build_query(Variables {
project: self.project.clone(),
service,
cursor: "".to_string(),
limit: self.limit,
since,
limit: Some(limit),
});

let client = ApiClient::new();
let res: Response<deployment_logs::ResponseData> = client.post(&request_body).await?;
let res: Response<ResponseData> = self.client.post(&request_body).await?;
if let Some(errors) = res.errors {
for err in errors {
println!("Error: {}", err.message);
}
return Ok(());
let error_message = errors
.into_iter()
.map(|err| err.message)
.collect::<Vec<_>>()
.join(", ");
return Err(anyhow::anyhow!(error_message));
}

let entries = res
let logs = res
.data
.and_then(|data| data.deployment)
.map(|deployment| deployment.logs.entries);

for e in entries.unwrap().iter() {
if e.trim() == "{}" {
println!("\n");
} else {
println!("{}", e);
}
.map(|deployment| deployment.logs)
.unwrap();

println!("{}", logs.content);

Ok(logs.until)
}

pub async fn stream(&self, since: Option<String>) -> Result<()> {
let running = Arc::new(AtomicBool::new(true));
let r = running.clone();
ctrlc::set_handler(move || {
r.store(false, Ordering::SeqCst);
})
.expect("Error setting Ctrl-C handler");

let mut since = self.query(since, 25).await?;
while running.load(Ordering::SeqCst) {
println!("{since}");
sleep(Duration::from_millis(1000)).await;
since = self.query(Some(since.clone()), 25).await?;
}

Ok(())
Expand Down

0 comments on commit 77e406d

Please sign in to comment.