Skip to content

Instantly share code, notes, and snippets.

@jaskiratr
Created March 19, 2024 15:41
Show Gist options
  • Save jaskiratr/245fa644afc8a172d9cc073d6b59f1a6 to your computer and use it in GitHub Desktop.
Save jaskiratr/245fa644afc8a172d9cc073d6b59f1a6 to your computer and use it in GitHub Desktop.
Testing New Relic Log Endpoint with Compute
/// <reference types="@fastly/js-compute" />
import { Logger } from 'fastly:logger';
addEventListener('fetch', (event) => event.respondWith(handleRequest(event)));
async function handleRequest(event) {
const logger = new Logger('my_new_relic_endpoint');
let logOutput = {
timestamp: new Date(Date.now()),
cache_status: 'ERROR',
client_ip: '127.0.0.1',
client_device_type: 'Chromebook',
client_os_name: 'Ubuntu',
client_os_version: '17.10 (Artful Aardvark)',
client_browser_name: 'Firefox',
client_browser_version: '113.0',
client_as_name: 'zayo bandwidth',
client_as_number: '1234',
client_connection_speed: 'broadband',
client_port: 63850,
client_rate_bps: 0,
client_recv_bytes: 74,
client_requests_count: 1,
client_resp_body_size_write: 56789,
client_resp_header_size_write: 1234,
client_resp_ttfb: 1.342,
client_rtt_us: 6818,
content_type: 'text/html; charset=utf-8',
domain: 'example.com',
fastly_datacenter: 'HNL',
fastly_host: 'cache-hnl00001',
fastly_is_edge: true,
fastly_region: 'US-Pacific',
fastly_server: 'cache-hnl00001-HNL',
host: 'example.com',
origin_host: 'example.com',
origin_name: 'n/a',
request: 'GET',
request_method: 'GET',
request_accept_charset: 'utf-8',
request_accept_language: 'en-US',
request_referer: '',
request_user_agent: 'curl/7.68.0',
resp_status: '200',
response: 'OK. Testing Log Endpoint',
service_id: 'U7w1m3BSxe6ldZwPrZtGB3',
// service_version: '29',
status: '503',
time_start: '2023-05-18T23:21:52Z',
time_end: '2023-05-18T23:21:53Z',
time_elapsed: 237,
tls_cipher: 'TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256',
tls_version: 'TLS 1.2',
url: '/',
user_agent: 'curl/7.68.0',
user_city: 'san francisco',
user_country_code: 'US',
user_continent_code: 'NA',
user_region: 'CA'
};
logger.log(logOutput);
return new Response(JSON.stringify(logOutput, null, 2), { status: 200 });
}
// {
// "client_ip": "%{req.http.Fastly-Client-IP}V",
// "geo_country": "%{client.geo.country_name}V",
// "url": "%{json.escape(req.url)}V",
// "request_referer": "%{json.escape(req.http.referer)}V",
// "request_user_agent": "%{json.escape(req.http.User-Agent)}V",
// "fastly_is_edge": %{if(fastly.ff.visits_this_service == 0, "true", "false")}V,
// "response_state": "%{json.escape(fastly_info.state)}V",
// "response_status": %{resp.status}V,
// "response_reason": %{if(resp.response, "%22"+json.escape(resp.response)+"%22", "null")}V,
// "response_body_size": %{resp.body_bytes_written}V,
// "request_method": "%{json.escape(req.method)}V",
// "request_protocol": "%{json.escape(req.proto)}V",
// "fastly_server": "%{json.escape(server.identity)}V",
// "host": "%{if(req.http.Fastly-Orig-Host, req.http.Fastly-Orig-Host, req.http.Host)}V"
// }
//! Compute logging demo
use fastly::http::{header, Method, StatusCode};
use fastly::{mime, Error, Request, Response};
use serde_json::json;
#[fastly::main]
fn main(req: Request) -> Result<Response, Error> {
// Filter request methods...
match req.get_method() {
// Allow GET and HEAD requests.
&Method::GET | &Method::HEAD => (),
// Deny anything else.
_ => {
return Ok(Response::from_status(StatusCode::METHOD_NOT_ALLOWED)
.with_header(header::ALLOW, "GET, HEAD")
.with_body_text_plain("This method is not allowed\n"))
}
};
// Pattern match on the path...
match req.get_path() {
// If request is to the `/` path...
"/" => {
// Initialize the logger with the one endpoint
// Notice we are echoing to stdout, so we don't need separate println! for log-tailing
log_fastly::Logger::builder()
.max_level(log::LevelFilter::Info)
.default_endpoint("my_endpoint")
.echo_stdout(true)
.init();
// Get some request data to log
let ts = chrono::Utc::now();
let record = json!({
"timestamp": ts.format("%F %T%.6f %Z").to_string(),
"trace_id": std::env::var("FASTLY_TRACE_ID").unwrap_or_else(|_| String::new()),
"client_ip": req.get_client_ip_addr().unwrap().to_string(),
"host": req.get_header_str("Host"),
"request_method": req.get_method_str(),
"url": req.get_url_str(),
});
// Send the logs
// note we didn't specify a target so it goes to `my_endpoint`, which we set as the default
// We could have also specified the target log::info!(target: "my_endpoint", "{}", record.to_string())
log::info!("{}", record.to_string());
// Send a default synthetic response.
Ok(Response::from_status(StatusCode::OK)
.with_content_type(mime::TEXT_HTML_UTF_8)
.with_body(include_str!("welcome-to-compute.html")))
}
// Catch all other requests and return a 404.
_ => Ok(Response::from_status(StatusCode::NOT_FOUND)
.with_body_text_plain("The page you requested could not be found\n")),
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment