feat: tokio dump

This commit is contained in:
evenyag
2024-11-08 22:39:55 +08:00
parent 3f9bf48161
commit a2eb46132f
3 changed files with 79 additions and 3 deletions

View File

@@ -267,13 +267,15 @@ git = "https://github.com/GreptimeTeam/greptime-meter.git"
rev = "a10facb353b41460eeb98578868ebf19c2084fac"
[profile.release]
debug = 1
# debug = 1
split-debuginfo = "off"
[profile.nightly]
inherits = "release"
strip = "debuginfo"
split-debuginfo = "off"
# strip = "debuginfo"
lto = "thin"
debug = false
# debug = false
incremental = false
[profile.ci]

View File

@@ -77,6 +77,7 @@ use crate::query_handler::{
use crate::server::Server;
pub mod authorize;
pub mod dump;
pub mod dyn_log;
pub mod event;
pub mod handler;
@@ -744,6 +745,7 @@ impl HttpServer {
"/log_level",
routing::get(dyn_log::dyn_log_handler).post(dyn_log::dyn_log_handler),
)
.route("/dump_tasks", routing::get(dump::dump_tasks_handler))
.nest(
"/prof",
Router::new()

View File

@@ -0,0 +1,72 @@
// Copyright 2023 Greptime Team
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
use std::fmt::Write;
use std::time::Duration;
use axum::extract::Query;
use axum::http::StatusCode;
use axum::response::IntoResponse;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use tokio::io::AsyncWriteExt;
use tokio::runtime::Handle;
use crate::error::Result;
#[derive(Serialize, Deserialize, Debug, JsonSchema)]
#[serde(default)]
pub struct DumpQuery {
seconds: u64,
path: String,
}
impl Default for DumpQuery {
fn default() -> DumpQuery {
DumpQuery {
seconds: 5,
path: "/tmp/greptimedb/dump-tasks.txt".to_string(),
}
}
}
#[axum_macros::debug_handler]
pub async fn dump_tasks_handler(Query(req): Query<DumpQuery>) -> Result<impl IntoResponse> {
common_telemetry::info!("Dump start, request: {:?}", req);
let handle = Handle::current();
let Ok(mut file) = tokio::fs::File::create(&req.path).await.inspect_err(|e| {
common_telemetry::error!(e; "Failed to open to {}", req.path);
}) else {
return Ok((StatusCode::INTERNAL_SERVER_ERROR, "Failed to open file."));
};
if let Ok(dump) = tokio::time::timeout(Duration::from_secs(req.seconds), handle.dump()).await {
for (i, task) in dump.tasks().iter().enumerate() {
let trace = task.trace();
let mut lines = String::new();
writeln!(lines, "TASK {i}:").unwrap();
writeln!(lines, "{trace}\n").unwrap();
if let Err(e) = file.write_all(lines.as_bytes()).await {
common_telemetry::error!(e; "Failed to open to {}", req.path);
return Ok((StatusCode::INTERNAL_SERVER_ERROR, "Failed to write file."));
}
}
} else {
common_telemetry::info!("Dump tasks timeout.");
return Ok((StatusCode::REQUEST_TIMEOUT, "Dump tasks timeout."));
}
common_telemetry::info!("Dump tasks done.");
Ok((StatusCode::OK, "Dump tasks done."))
}