Send Logs to Logging Services
You can use this document to learn how to send logs to third-party logging services. Specifically, this document provides examples for a self-hosted ElasticSearch cluster and the LogDNA SaaS.
Viewing a Sample Script for ElasticSearch
In the script below, update the following strings:
-
ELASTIC_URL
- Replace this string with your ElasticSearch cluster ingestion URL.
-
YOURBASICAUTH
- Replace this string with your basic authentication credentials.
- To learn more, see Generate basic authentication credentials.
Review the following sample script:
let requests = [];
addEventListener('fetch', event => {
event.respondWith(fetchAndLog(event));
});
async function fetchAndLog(event) {
const response = await fetch(event.request);
requests.push(getRequestData(event.request, response));
return response;
}
async function getRequestData(request, response) {
var data = {
'timestamp': Date.now(),
'x-sp-client-ip': request.headers.get("x-sp-client-ip"),
};
console.log(JSON.stringify(data));
var url = "ELASTIC_URL";
let myHeaders = new Headers();
myHeaders.append("Content-Type", "application/json");
myHeaders.append(
"Authorization",
"Basic YOURBASICAUTH"
);
await fetch(url, {
method: "POST",
body: JSON.stringify(data),
headers: myHeaders
});
}
Viewing a Sample Script for LogDNA
In the script below, update the following strings:
-
YOUR APP NAME
- Replace this string with your application name so that you can identify your application in the logs.
-
YOURBASICAUTH
- Replace this string with your basic authentication credentials.
- To learn more, see Generate basic authentication credentials.
-
domain.com
- Replace this string with the domain that serves your requests.
Review the following sample script:
let requests = [];
let workerInception, workerId, requestStartTime, requestEndTime;
let batchIsRunning = false;
const maxRequestsPerBatch = 150;
addEventListener("fetch", event => {
event.respondWith(logRequests(event));
});
async function logRequests(event) {
if (!batchIsRunning) {
handleBatch(event);
}
if (requests.length >= maxRequestsPerBatch) {
postRequests();
}
requestStartTime = Date.now();
if (!workerInception) workerInception = Date.now();
if (!workerId) workerId = makeid(6);
const response = await fetch(event.request);
requestEndTime = Date.now();
requests.push(getRequestData(event.request, response));
return response;
}
async function handleBatch(event) {
batchIsRunning = true;
await sleep(10000);
try {
if (requests.length) postRequests();
} catch (e) {}
requests = [];
batchIsRunning = false;
}
function sleep(ms) {
return new Promise(resolve => {
setTimeout(resolve, ms);
});
}
function getRequestData(request, re) {
let data = {
app: "YOUR APP NAME",
timestamp: Date.now(),
meta: {
ua: request.headers.get("user-agent"),
referer: request.headers.get("Referer") || "empty",
ip: request.headers.get("x-sp-client-ip"),
countryCode: (request.headers.get("x-sp-client-geo-countryCode") || {})
.country,
workerInception: workerInception,
workerId: workerId,
url: request.url,
method: request.method,
x_forwarded_for: request.headers.get("x_forwarded_for") || "0.0.0.0",
status: (re || {}).status,
originTime: requestEndTime - requestStartTime
}
};
data.line =
data.meta.status +
" " +
data.meta.countryCode +
" " +
data.meta.originTime +
"ms" +
" " +
data.meta.ip +
" " +
data.meta.url;
return data;
}
async function postRequests() {
let data = JSON.stringify({ lines: requests });
const hostname = "domain.com";
let myHeaders = new Headers();
myHeaders.append("Content-Type", "application/json; charset=UTF-8");
myHeaders.append(
"Authorization",
"Basic YOURBASICAUTH"
);
try {
const res = await fetch(
"https://logs.logdna.com/logs/ingest?tag=worker&hostname=" + hostname,
{
method: "POST",
headers: myHeaders,
body: data
}
);
requests = [];
} catch (err) {
// console.log(err.stack || err);
}
}
function makeid(len) {
let text = "";
const possible = "ABCDEFGHIJKLMNPQRSTUVWXYZ0123456789";
for (let i = 0; i < len; i++)
text += possible.charAt(Math.floor(Math.random() * possible.length));
return text;
}
Generating Basic Authentication Credentials
Basic authentication is a method used to authenticate with a remote web server with a username and password. To achieve this, pass an authorization header that contains the method (basic) and the username and password, joined by a :
, which is then base64 encoded.
For example, if your username is stackpath
and your password is logging
, then you would need to base64 encode the string stackpath:logging
, which gives the output of c3RhY2twYXRoOmxvZ2dpbmc=
. This information would be passed in the request via the Authorization header as below:
Authorization: Basic c3RhY2twYXRoOmxvZ2dpbmc=
Review the following examples to learn how to generate a base64-encoded string. StackPath recommends that you do not use an online service to encode this string.
For MacOS / Linux users:
From a terminal, execute the following script and replace stackpath:logging with your credentials:
echo -n 'stackpath:logging' | openssl base64
For Windows users:
From a command prompt, execute the following script and replace stackpath:logging with your credentials:
powershell "[convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes(\"stackpath:logging\"))"
Updated 30 days ago