Skip to content

Commit

Permalink
feat(serverless,website): add statistics (#156)
Browse files Browse the repository at this point in the history
* feat: stats

* refactor: use proper metrics

* feat: correct cpu time, add memory and bytes in/out

* refactor: remove stats table

* feat(serverless): add functionid to stats

* feat(website): show stats using prometheus API

* refactor: improve charts

* chore: add changeset

* chore: add runtime changeset
  • Loading branch information
QuiiBz authored Oct 1, 2022
1 parent 73120dc commit dcfdf5d
Show file tree
Hide file tree
Showing 28 changed files with 616 additions and 270 deletions.
5 changes: 5 additions & 0 deletions .changeset/eight-worms-own.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@lagon/runtime': patch
---

Add cpu and memory statistics
6 changes: 6 additions & 0 deletions .changeset/wet-cats-flow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@lagon/serverless': patch
'@lagon/website': patch
---

Add statistics
118 changes: 118 additions & 0 deletions Cargo.lock

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

24 changes: 23 additions & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,28 @@ services:
- 3306:3306
volumes:
- mysql:/var/lib/mysql

prometheus:
image: prom/prometheus
container_name: prometheus
restart: always
ports:
- 9090:9090
volumes:
- ./docker/prometheus/prometheus.yml:/etc/prometheus/prometheus.yml
- prometheus:/prometheus

grafana:
image: grafana/grafana
container_name: grafana
restart: always
ports:
- 3001:3000
volumes:
- ./docker/grafana/datasources:/etc/grafana/provisioning/datasources
- grafana:/var/lib/grafana
volumes:
redis:
mysql:
mysql:
prometheus:
grafana:
6 changes: 6 additions & 0 deletions docker/grafana/datasources/prometheus_ds.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
datasources:
- name: Prometheus
access: proxy
type: prometheus
url: http://host.docker.internal:9090
isDefault: true
7 changes: 7 additions & 0 deletions docker/prometheus/prometheus.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
global:
scrape_interval: 1s

scrape_configs:
- job_name: 'serverless'
static_configs:
- targets: ['host.docker.internal:9000']
6 changes: 4 additions & 2 deletions packages/cli/src/commands/login.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,13 @@ struct CliRequest {
}

pub async fn login() -> io::Result<()> {
if (get_token()?).is_some() && !Confirm::new()
if (get_token()?).is_some()
&& !Confirm::new()
.with_prompt(info(
"You are already logged in. Are you sure you want to log in again?",
))
.interact()? {
.interact()?
{
return Err(Error::new(ErrorKind::Other, "Login aborted."));
}

Expand Down
11 changes: 10 additions & 1 deletion packages/runtime/src/http/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use std::collections::HashMap;
use std::time::Duration;

use crate::utils::{extract_v8_string, v8_string};

Expand Down Expand Up @@ -83,6 +82,11 @@ impl Request {

request
}

// TODO: Return the full request length
pub fn len(&self) -> usize {
self.body.len()
}
}

#[derive(Debug, PartialEq)]
Expand Down Expand Up @@ -156,6 +160,11 @@ impl Response {
status,
})
}

// TODO: Return the full response length
pub fn len(&self) -> usize {
self.body.len()
}
}

#[derive(Debug, PartialEq)]
Expand Down
48 changes: 38 additions & 10 deletions packages/runtime/src/isolate/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ struct IsolateState {
promises: Vec<JoinHandle<()>>,
}

pub struct IsolateStatistics {
pub cpu_time: Duration,
pub memory_usage: usize,
}

pub struct IsolateOptions {
pub code: String,
pub environment_variables: Option<HashMap<String, String>>,
Expand Down Expand Up @@ -133,7 +138,7 @@ impl Isolate {
state.global.clone()
}

pub fn run(&mut self, request: Request) -> RunResult {
pub fn run(&mut self, request: Request) -> (RunResult, Option<IsolateStatistics>) {
let thread_safe_handle = self.isolate.thread_safe_handle();

let state = self.global_realm();
Expand All @@ -146,7 +151,10 @@ impl Isolate {
None => {
self.compilation_error = Some("Failed to get runtime code".to_string());

return RunResult::Error(self.compilation_error.clone().unwrap());
return (
RunResult::Error(self.compilation_error.clone().unwrap()),
None,
);
}
};

Expand Down Expand Up @@ -199,7 +207,7 @@ impl Isolate {
}

if let Some(error) = &self.compilation_error {
return RunResult::Error(error.clone());
return (RunResult::Error(error.clone()), None);
}

let request = request.to_v8_request(try_catch);
Expand Down Expand Up @@ -266,16 +274,36 @@ impl Isolate {
};
}

// let mut heap_statistics = v8::HeapStatistics::default();
// try_catch.get_heap_statistics(&mut heap_statistics);
// println!("count: {} used heap size: {}", self.count.load(Ordering::SeqCst), heap_statistics.used_heap_size());

let cpu_time = now.elapsed();
let memory_usage = self.count.load(Ordering::SeqCst);
self.count.store(0, Ordering::SeqCst);

match Response::from_v8_response(try_catch, response) {
Some(response) => RunResult::Response(response),
None => extract_error(try_catch),
Some(response) => (
RunResult::Response(response),
Some(IsolateStatistics {
cpu_time,
memory_usage,
}),
),
None => (extract_error(try_catch), None),
}
}
None => match *terminated.read().unwrap() {
ExecutionResult::MemoryReached => RunResult::MemoryLimit(),
ExecutionResult::TimeoutReached => RunResult::Timeout(),
_ => extract_error(try_catch),
},
None => {
self.count.store(0, Ordering::SeqCst);

let run_result = match *terminated.read().unwrap() {
ExecutionResult::MemoryReached => RunResult::MemoryLimit(),
ExecutionResult::TimeoutReached => RunResult::Timeout(),
_ => extract_error(try_catch),
};

return (run_result, None);
}
}
}
}
Expand Down
Loading

0 comments on commit dcfdf5d

Please sign in to comment.