servers/http/
mem_prof.rs

1// Copyright 2023 Greptime Team
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#[cfg(feature = "mem-prof")]
16use axum::Form;
17#[cfg(feature = "mem-prof")]
18use axum::extract::Query;
19use axum::http::StatusCode;
20use axum::response::IntoResponse;
21use serde::{Deserialize, Serialize};
22
23/// Output format.
24#[derive(Debug, Default, Serialize, Deserialize)]
25#[serde(rename_all = "snake_case")]
26pub enum Output {
27    /// google’s pprof format report in protobuf.
28    Proto,
29    /// jeheap text format. Define by jemalloc.
30    #[default]
31    Text,
32    /// svg flamegraph.
33    Flamegraph,
34}
35
36#[derive(Default, Serialize, Deserialize, Debug)]
37#[serde(default)]
38pub struct MemPprofQuery {
39    output: Output,
40}
41
42#[cfg(feature = "mem-prof")]
43#[axum_macros::debug_handler]
44pub async fn mem_prof_handler(
45    Query(req): Query<MemPprofQuery>,
46) -> crate::error::Result<impl IntoResponse> {
47    use snafu::ResultExt;
48
49    use crate::error::DumpProfileDataSnafu;
50
51    let dump = match req.output {
52        Output::Proto => common_mem_prof::dump_pprof().await,
53        Output::Text => common_mem_prof::dump_profile().await,
54        Output::Flamegraph => common_mem_prof::dump_flamegraph().await,
55    }
56    .context(DumpProfileDataSnafu)?;
57
58    Ok((StatusCode::OK, dump))
59}
60
61#[cfg(feature = "mem-prof")]
62#[axum_macros::debug_handler]
63pub async fn activate_heap_prof_handler() -> crate::error::Result<impl IntoResponse> {
64    use snafu::ResultExt;
65
66    use crate::error::DumpProfileDataSnafu;
67
68    common_mem_prof::activate_heap_profile().context(DumpProfileDataSnafu)?;
69
70    Ok((StatusCode::OK, "Heap profiling activated"))
71}
72
73#[cfg(feature = "mem-prof")]
74#[axum_macros::debug_handler]
75pub async fn deactivate_heap_prof_handler() -> crate::error::Result<impl IntoResponse> {
76    use snafu::ResultExt;
77
78    use crate::error::DumpProfileDataSnafu;
79
80    common_mem_prof::deactivate_heap_profile().context(DumpProfileDataSnafu)?;
81
82    Ok((StatusCode::OK, "Heap profiling deactivated"))
83}
84
85#[cfg(not(feature = "mem-prof"))]
86#[axum_macros::debug_handler]
87pub async fn mem_prof_handler() -> crate::error::Result<impl IntoResponse> {
88    Ok((
89        StatusCode::NOT_IMPLEMENTED,
90        "The 'mem-prof' feature is disabled",
91    ))
92}
93
94#[cfg(not(feature = "mem-prof"))]
95#[axum_macros::debug_handler]
96pub async fn activate_heap_prof_handler() -> crate::error::Result<impl IntoResponse> {
97    Ok((
98        StatusCode::NOT_IMPLEMENTED,
99        "The 'mem-prof' feature is disabled",
100    ))
101}
102
103#[cfg(feature = "mem-prof")]
104#[axum_macros::debug_handler]
105pub async fn heap_prof_status_handler() -> crate::error::Result<impl IntoResponse> {
106    use snafu::ResultExt;
107
108    use crate::error::DumpProfileDataSnafu;
109
110    let is_active = common_mem_prof::is_heap_profile_active().context(DumpProfileDataSnafu)?;
111
112    Ok((StatusCode::OK, format!("{{\"active\": {}}}", is_active)))
113}
114
115#[cfg(not(feature = "mem-prof"))]
116#[axum_macros::debug_handler]
117pub async fn deactivate_heap_prof_handler() -> crate::error::Result<impl IntoResponse> {
118    Ok((
119        StatusCode::NOT_IMPLEMENTED,
120        "The 'mem-prof' feature is disabled",
121    ))
122}
123
124#[cfg(not(feature = "mem-prof"))]
125#[axum_macros::debug_handler]
126pub async fn heap_prof_status_handler() -> crate::error::Result<impl IntoResponse> {
127    Ok((
128        StatusCode::NOT_IMPLEMENTED,
129        "The 'mem-prof' feature is disabled",
130    ))
131}
132
133#[cfg(feature = "mem-prof")]
134#[derive(Deserialize)]
135pub struct GdumpToggleForm {
136    activate: bool,
137}
138
139#[cfg(feature = "mem-prof")]
140#[axum_macros::debug_handler]
141pub async fn gdump_toggle_handler(
142    Form(form): Form<GdumpToggleForm>,
143) -> crate::error::Result<impl IntoResponse> {
144    use snafu::ResultExt;
145
146    use crate::error::DumpProfileDataSnafu;
147
148    common_mem_prof::set_gdump_active(form.activate).context(DumpProfileDataSnafu)?;
149
150    let msg = if form.activate {
151        "gdump activated"
152    } else {
153        "gdump deactivated"
154    };
155    Ok((StatusCode::OK, msg))
156}
157
158#[cfg(not(feature = "mem-prof"))]
159#[axum_macros::debug_handler]
160pub async fn gdump_toggle_handler() -> crate::error::Result<impl IntoResponse> {
161    Ok((
162        StatusCode::NOT_IMPLEMENTED,
163        "The 'mem-prof' feature is disabled",
164    ))
165}
166
167#[cfg(feature = "mem-prof")]
168#[axum_macros::debug_handler]
169pub async fn gdump_status_handler() -> crate::error::Result<impl IntoResponse> {
170    use snafu::ResultExt;
171
172    use crate::error::DumpProfileDataSnafu;
173
174    let is_active = common_mem_prof::is_gdump_active().context(DumpProfileDataSnafu)?;
175    Ok((StatusCode::OK, format!("{{\"active\": {}}}", is_active)))
176}
177
178#[cfg(not(feature = "mem-prof"))]
179#[axum_macros::debug_handler]
180pub async fn gdump_status_handler() -> crate::error::Result<impl IntoResponse> {
181    Ok((
182        StatusCode::NOT_IMPLEMENTED,
183        "The 'mem-prof' feature is disabled",
184    ))
185}