1use std::collections::HashMap;
2
3use reqwest::Method;
4use serde::{Deserialize, Serialize};
5
6use super::Client;
7use crate::error::Result;
8
9#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
11#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
12pub enum LogState {
13 Created,
15 Active,
17 Retry,
19 Error,
21 Delivered,
23 Failed,
25 Cancelled,
27 CancelRequested,
29 InProgress,
31 #[serde(other)]
33 Unknown,
34}
35
36#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
38#[serde(rename_all = "camelCase")]
39pub struct LogEntry {
40 pub time: u64,
42 pub state: LogState,
44 pub message_id: String,
46 pub next_delivery_time: Option<u64>,
48 pub error: Option<String>,
50 pub url: Option<String>,
52 pub topic_name: Option<String>,
54 pub endpoint_name: Option<String>,
56 pub header: Option<HashMap<String, Vec<String>>>,
58 pub body: Option<String>,
60 pub body_base64: Option<String>,
62 pub response_status: Option<u16>,
64 pub label: Option<String>,
66 pub queue_name: Option<String>,
68 pub schedule_id: Option<String>,
70 pub caller_ip: Option<String>,
72 pub flow_control_key: Option<String>,
74}
75
76#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
78pub struct LogsPage {
79 pub cursor: Option<String>,
81 pub logs: Vec<LogEntry>,
83}
84
85#[derive(Debug, Clone, Default, PartialEq, Eq)]
87pub struct LogFilter {
88 pub cursor: Option<String>,
90 pub message_id: Option<String>,
92 pub state: Option<LogState>,
94 pub url: Option<String>,
96 pub url_group_name: Option<String>,
98 pub endpoint_name: Option<String>,
100 pub schedule_id: Option<String>,
102 pub queue_name: Option<String>,
104 pub caller_ip: Option<String>,
106 pub flow_control_key: Option<String>,
108 pub response_status: Option<u16>,
110 pub label: Option<String>,
112 pub from_date: Option<u64>,
114 pub to_date: Option<u64>,
116 pub count: Option<u32>,
118}
119
120pub struct LogsApi<'a> {
122 pub(crate) client: &'a Client,
123}
124
125impl LogsApi<'_> {
126 pub async fn list(&self, filter: &LogFilter) -> Result<LogsPage> {
128 self.client
129 .http
130 .send_json(
131 Method::GET,
132 "v2/logs",
133 &log_filter_query(filter),
134 None,
135 None,
136 )
137 .await
138 }
139}
140
141fn log_filter_query(filter: &LogFilter) -> Vec<(String, String)> {
142 let mut query = Vec::new();
143
144 if let Some(cursor) = &filter.cursor {
145 query.push((String::from("cursor"), cursor.clone()));
146 }
147 if let Some(message_id) = &filter.message_id {
148 query.push((String::from("messageId"), message_id.clone()));
149 }
150 if let Some(state) = &filter.state {
151 query.push((String::from("state"), serde_state(state)));
152 }
153 if let Some(url) = &filter.url {
154 query.push((String::from("url"), url.clone()));
155 }
156 if let Some(url_group_name) = &filter.url_group_name {
157 query.push((String::from("topicName"), url_group_name.clone()));
158 }
159 if let Some(endpoint_name) = &filter.endpoint_name {
160 query.push((String::from("endpointName"), endpoint_name.clone()));
161 }
162 if let Some(schedule_id) = &filter.schedule_id {
163 query.push((String::from("scheduleId"), schedule_id.clone()));
164 }
165 if let Some(queue_name) = &filter.queue_name {
166 query.push((String::from("queueName"), queue_name.clone()));
167 }
168 if let Some(caller_ip) = &filter.caller_ip {
169 query.push((String::from("callerIp"), caller_ip.clone()));
170 }
171 if let Some(flow_control_key) = &filter.flow_control_key {
172 query.push((String::from("flowControlKey"), flow_control_key.clone()));
173 }
174 if let Some(response_status) = filter.response_status {
175 query.push((String::from("responseStatus"), response_status.to_string()));
176 }
177 if let Some(label) = &filter.label {
178 query.push((String::from("label"), label.clone()));
179 }
180 if let Some(from_date) = filter.from_date {
181 query.push((String::from("fromDate"), from_date.to_string()));
182 }
183 if let Some(to_date) = filter.to_date {
184 query.push((String::from("toDate"), to_date.to_string()));
185 }
186 if let Some(count) = filter.count {
187 query.push((String::from("count"), count.to_string()));
188 }
189
190 query
191}
192
193fn serde_state(state: &LogState) -> String {
194 match state {
195 LogState::Created => String::from("CREATED"),
196 LogState::Active => String::from("ACTIVE"),
197 LogState::Retry => String::from("RETRY"),
198 LogState::Error => String::from("ERROR"),
199 LogState::Delivered => String::from("DELIVERED"),
200 LogState::Failed => String::from("FAILED"),
201 LogState::Cancelled => String::from("CANCELLED"),
202 LogState::CancelRequested => String::from("CANCEL_REQUESTED"),
203 LogState::InProgress => String::from("IN_PROGRESS"),
204 LogState::Unknown => String::from("UNKNOWN"),
205 }
206}