Skip to content

Commit

Permalink
test: add test for logger
Browse files Browse the repository at this point in the history
  • Loading branch information
vicanso committed Mar 24, 2024
1 parent bb36f28 commit 428fdf6
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 17 deletions.
77 changes: 61 additions & 16 deletions src/proxy/logger.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::utils;

use super::state::State;
use bytesize::ByteSize;
use pingora::proxy::Session;
use pingora::http::RequestHeader;
use regex::Regex;
use std::time::{Duration, Instant};
use substring::Substring;
Expand Down Expand Up @@ -227,8 +227,8 @@ impl From<&str> for Parser {
}
}

fn get_header_value<'a>(session: &'a Session, key: &str) -> Option<&'a str> {
if let Some(value) = session.get_header(key) {
fn get_header_value<'a>(req_header: &'a RequestHeader, key: &str) -> Option<&'a str> {
if let Some(value) = req_header.headers.get(key) {
if let Ok(value) = value.to_str() {
return Some(value);
}
Expand All @@ -237,7 +237,7 @@ fn get_header_value<'a>(session: &'a Session, key: &str) -> Option<&'a str> {
}

impl Parser {
pub fn format(&self, session: &Session, ctx: &State) -> String {
pub fn format(&self, req_header: &RequestHeader, ctx: &State) -> String {
let mut buf = String::with_capacity(1024);
for tag in self.tags.iter() {
match tag.category {
Expand All @@ -247,54 +247,54 @@ impl Parser {
}
}
TagCategory::Host => {
if let Some(host) = session.req_header().uri.host() {
if let Some(host) = get_header_value(req_header, "Host") {
buf.push_str(host);
}
}
TagCategory::Method => {
buf.push_str(session.req_header().method.as_str());
buf.push_str(req_header.method.as_str());
}
TagCategory::Path => {
buf.push_str(session.req_header().uri.path());
buf.push_str(req_header.uri.path());
}
TagCategory::Proto => {
if session.is_http2() {
if ctx.http_version == 2 {
buf.push_str("HTTP/2.0");
} else {
buf.push_str("HTTP/1.1");
}
}
TagCategory::Query => {
if let Some(query) = session.req_header().uri.query() {
if let Some(query) = req_header.uri.query() {
buf.push_str(query);
}
}
TagCategory::Remote => {
// TODO
}
TagCategory::ClientIp => {
if let Some(value) = get_header_value(session, "X-Forwarded-For") {
if let Some(value) = get_header_value(req_header, "X-Forwarded-For") {
let arr: Vec<&str> = value.split(',').collect();
if !arr.is_empty() {
buf.push_str(arr[0].trim());
}
} else if let Some(value) = get_header_value(session, "X-Real-Ip") {
} else if let Some(value) = get_header_value(req_header, "X-Real-Ip") {
buf.push_str(value);
}
}
TagCategory::Scheme => {
// TODO
}
TagCategory::Uri => {
buf.push_str(&session.req_header().uri.to_string());
buf.push_str(&req_header.uri.to_string());
}
TagCategory::Referer => {
if let Some(value) = get_header_value(session, "Referer") {
if let Some(value) = get_header_value(req_header, "Referer") {
buf.push_str(value);
}
}
TagCategory::UserAgent => {
if let Some(value) = get_header_value(session, "User-Agent") {
if let Some(value) = get_header_value(req_header, "User-Agent") {
buf.push_str(value);
}
}
Expand Down Expand Up @@ -334,7 +334,7 @@ impl Parser {
}
TagCategory::Cookie => {
let cookie_name = tag.data.clone().unwrap_or_default();
let cookie_value = get_header_value(session, "Cookie").unwrap_or_default();
let cookie_value = get_header_value(req_header, "Cookie").unwrap_or_default();
for item in cookie_value.split(';') {
if let Some([k, v]) = utils::split_to_two_trim(item, "=") {
if k == cookie_name {
Expand All @@ -345,7 +345,7 @@ impl Parser {
}
TagCategory::RequestHeader => {
if let Some(key) = &tag.data {
if let Some(value) = get_header_value(session, key) {
if let Some(value) = get_header_value(req_header, key) {
buf.push_str(value);
}
}
Expand Down Expand Up @@ -381,3 +381,48 @@ impl Parser {
buf
}
}

#[cfg(test)]
mod tests {
use super::Parser;
use crate::proxy::state::State;
use pingora::http::RequestHeader;
use pretty_assertions::assert_eq;
use std::collections::HashMap;

#[test]
fn test_logger() {
let p: Parser = "{host} {method} {path} {proto} {query} {remote} {client-ip} \
{scheme} {uri} {referer} {user-agent} {size} \
{size-human} {status} {latency} {latency-human} {payload-size} {payload-size-human} \
{~deviceId} {>accept} {<content-type} {:reused}"
.into();
let mut req_header =
RequestHeader::build_no_case("GET", b"/vicanso/pingap?size=1", Some(4)).unwrap();
req_header.insert_header("Host", "github.com").unwrap();
req_header
.insert_header("Referer", "https://github.com/")
.unwrap();
req_header
.insert_header("User-Agent", "pingap/0.1.1")
.unwrap();
req_header.insert_header("Cookie", "deviceId=abc").unwrap();
req_header
.insert_header("Accept", "application/json")
.unwrap();
let mut m = HashMap::new();
m.insert("content-type".to_string(), "json".to_string());
let ctx = State {
response_body_size: 1024,
reused: true,
response_headers: Some(m),
..Default::default()
};
let log = p.format(&req_header, &ctx);
assert_eq!(
"github.com GET /vicanso/pingap HTTP/1.1 size=1 /vicanso/pingap?size=1 \
https://github.com/ pingap/0.1.1 1024 1.0KB 0 0 0ns abc application/json json true",
log
);
}
}
6 changes: 5 additions & 1 deletion src/proxy/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,9 @@ impl ProxyHttp for Server {
{
ctx.processing = self.processing.fetch_add(1, Ordering::Relaxed);
self.accepted.fetch_add(1, Ordering::Relaxed);
if session.is_http2() {
ctx.http_version = 2;
}
if let Some(stats_path) = &self.stats_path {
if stats_path == session.req_header().uri.path() {
let size = self
Expand Down Expand Up @@ -497,9 +500,10 @@ impl ProxyHttp for Server {
Self::CTX: Send + Sync,
{
self.processing.fetch_add(-1, Ordering::Relaxed);

if let Some(p) = &self.log_parser {
ctx.response_size = session.body_bytes_sent();
info!("{}", p.format(session, ctx));
info!("{}", p.format(session.req_header(), ctx));
}
}
}
2 changes: 2 additions & 0 deletions src/proxy/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use std::collections::HashMap;
use std::time::Instant;

pub struct State {
pub http_version: u8,
pub processing: i32,
pub created_at: Instant,
pub status: Option<StatusCode>,
Expand All @@ -17,6 +18,7 @@ pub struct State {
impl Default for State {
fn default() -> Self {
State {
http_version: 1,
processing: 0,
status: None,
created_at: Instant::now(),
Expand Down

0 comments on commit 428fdf6

Please sign in to comment.