Skip to content
This repository has been archived by the owner on Oct 27, 2024. It is now read-only.

Add files from log-app to ubiquity-logging repo #1

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions _worker.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { Env } from "./types/global";

export default {
async fetch(request: Request, env: Env) {
// Otherwise, serve the static assets.
// Without this, the Worker will error and no assets will be served.
return env.ASSETS.fetch(request);
},
};
44 changes: 44 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Log Viewer</title>
<link rel="stylesheet" href="./styles/index.css">
</head>

<body>
<div class="log-container">
<select id="filter">
<option value="all">All</option>
<option value="error">Error</option>
<option value="warn">Warning</option>
<option value="info">Info</option>
<option value="verbose">Verbose</option>
<option value="debug">Debug</option>
</select>
<button id="clear">Clear</button>
</div>
<table id="log-table">
<thead>
<tr>
<th>Message</th>
<th>Level</th>
<th>Timestamp</th>
<th>Comment URL</th>
</tr>
</thead>
<tbody id="log-body"></tbody>
</table>
<div id="json-modal" class="modal">
<div class="modal-content">
<span id="close-modal" class="close">&times;</span>
<pre id="json-content" class="json-content"></pre>
</div>
</div>
<script>var exports = {};</script>
<script type="application/javascript" src="./scripts/index.js"></script>
</body>

</html>
3 changes: 3 additions & 0 deletions scripts/constants/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export const SUPABASE_URL = "https://qzfjblxdroqrmlheoajw.supabase.co";
export const SUPABASE_KEY =
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InF6ZmpibHhkcm9xcm1saGVvYWp3Iiwicm9sZSI6ImFub24iLCJpYXQiOjE2ODA4NTMwMzMsImV4cCI6MTk5NjQyOTAzM30.BM_qkpX-egNdiMc0PDO_34bIaXHB7ewnr2k4U2hGFMM";
19 changes: 19 additions & 0 deletions scripts/esbuild-config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import esbuild from "esbuild";
const typescriptEntries = ["scripts/helpers/utils.ts", "scripts/index.ts", "scripts/constants/index.ts"];
export const entries = [...typescriptEntries];

export let esBuildContext = {
sourcemap: false,
entryPoints: entries,
bundle: true,
minify: false,
loader: {
".png": "dataurl",
".woff": "dataurl",
".woff2": "dataurl",
".eot": "dataurl",
".ttf": "dataurl",
".svg": "dataurl",
},
outdir: "scripts",
} as esbuild.BuildOptions;
3 changes: 3 additions & 0 deletions scripts/esbuild.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import esbuild from "esbuild";
import { esBuildContext } from "./esbuild-config";
esbuild.build(esBuildContext);
66 changes: 66 additions & 0 deletions scripts/helpers/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
export enum Level {
ERROR = "error",
WARN = "warn",
INFO = "info",
HTTP = "http",
VERBOSE = "verbose",
DEBUG = "debug",
SILLY = "silly",
}

export const createGitHubCommentURL = (orgName: string, repoName: string, issueNumber: number, commentId: number) => {
return `https://github.com/${orgName}/${repoName}/issues/${issueNumber}#issuecomment-${commentId}`;
};

export const isValidJson = (jsonString) => {
try {
JSON.parse(jsonString);
return true;
} catch (error) {
return false;
}
};

export const generateRandomId = (length) => {
return [...Array(length)].map(() => Math.random().toString(36)[2]).join("");
};

export const containsValidJson = (message: string): [boolean, string, string] => {
const jsonMatches = message.match(/\{.*\}/g); // Find JSON-like substrings
if (!jsonMatches) {
return [false, "", ""];
}

for (const match of jsonMatches) {
if (isValidJson(match)) {
const braceIndex = message.indexOf("{");
if (braceIndex !== -1) {
return [true, match, message.substring(0, braceIndex)];
}
return [true, match, ""];
}
}

return [false, "", ""];
};

export const getLevelString = (level: number) => {
switch (level) {
case 0:
return Level.ERROR;
case 1:
return Level.WARN;
case 2:
return Level.INFO;
case 3:
return Level.HTTP;
case 4:
return Level.VERBOSE;
case 5:
return Level.DEBUG;
case 6:
return Level.SILLY;
default:
return -1; // Invalid level
}
};
99 changes: 99 additions & 0 deletions scripts/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import { containsValidJson, createGitHubCommentURL, generateRandomId, getLevelString } from "./helpers/utils";
import { Logs } from "./types/log";
import { createClient } from "@supabase/supabase-js";
import { SUPABASE_URL, SUPABASE_KEY } from "./constants/index";

const filterSelect = document.getElementById("filter") as unknown as HTMLSelectElement;
const clearButton = document.getElementById("clear") as HTMLButtonElement;
const logBody = document.getElementById("log-body") as HTMLDivElement;

const jsonModal = document.getElementById("json-modal") as HTMLDivElement;
const closeModalButton = document.getElementById("close-modal") as HTMLButtonElement;
const jsonContent = document.getElementById("json-content") as HTMLDivElement;

const openJsonModal = (validJson) => {
jsonContent.textContent = validJson;

jsonModal.style.display = "flex";
};

const updateLogTable = () => {
const selectedFilter = filterSelect.value;
const filteredLogs = selectedFilter === "all" ? logs : logs.filter((log) => getLevelString(log.level) === selectedFilter);

logBody.innerHTML = "";
filteredLogs.forEach((log) => {
const classId = generateRandomId(10);
const commentUrl = createGitHubCommentURL(log.org_name, log.repo_name, log.issue_number, log.comment_id);
const row = document.createElement("tr");
const [validJson, match, beforeText] = containsValidJson(log.log_message);
row.innerHTML = `
${
validJson
? `<td class="log-cell">${beforeText} - <button id="button_${classId}">Show JSON</button></td>`
: `<td class="log-cell">${log.log_message}</td>`
}
<td>${getLevelString(log.level)}</td>
<td>${log.timestamp}</td>
<td><a href="${commentUrl}">Comment - ${log.comment_id}</a></td>
`;
logBody.appendChild(row);
let logCell = document.getElementsByClassName("log-cell");
if (validJson) {
// show modal button for valid json row
const showMoreButton = document.getElementById(`button_${classId}`) as HTMLButtonElement;
showMoreButton.addEventListener("click", () => {
if (validJson) {
openJsonModal(JSON.stringify(JSON.parse(match), null, 2)); // properly formatted json
}
});
}
// scroll to last added data
logCell[logCell.length - 1].scrollIntoView();
});
};

let logs: Logs[] = [];

const supabaseClient = createClient(SUPABASE_URL, SUPABASE_KEY);

const channel = supabaseClient
.channel("table-db-changes")
.on(
"postgres_changes",
{
event: "INSERT",
schema: "public",
table: "logs",
},
(payload) => handlePayload(payload)
)
.subscribe();

const handlePayload = (logEntry) => {
if (logEntry?.eventType !== "INSERT") return;
logs.push(logEntry.new);
updateLogTable();
};

filterSelect.addEventListener("change", () => {
updateLogTable();
});

clearButton.addEventListener("click", () => {
logs = [];
updateLogTable();
});

closeModalButton.addEventListener("click", () => {
jsonModal.style.display = "none";
});

window.addEventListener("click", (event) => {
if (event.target === jsonModal) {
jsonModal.style.display = "none";
}
});

// Initial update
updateLogTable();
15 changes: 15 additions & 0 deletions scripts/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"compilerOptions": {
"useDefineForClassFields": true,
"allowJs": false,
"esModuleInterop": true,
"module": "CommonJS",
"allowSyntheticDefaultImports": true,
"strict": false,
"forceConsistentCasingInFileNames": true,
"target": "esnext" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */,
"lib": ["esnext", "dom", "dom.iterable"] /* Specify a set of bundled library declaration files that describe the target runtime environment. */
},
"include": ["./helpers", "./constants", "./index.ts"],
"exclude": ["./esbuild.ts", "./esbuild-config.ts"]
}
9 changes: 9 additions & 0 deletions scripts/types/log.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export type Logs = {
timestamp: string;
log_message: string;
level: number;
repo_name: string;
org_name: string;
comment_id: number;
issue_number: number;
};
Loading