Logtape (https://logtape.org/) is a JavaScript library to manage logs. By default Logtape is only available for backend Javascript but you can use with moderne browser.
<script type="module">
import { configure, getLogger, getConsoleSink } from "https://esm.sh/@logtape/logtape";
await configure({
sinks: {
console: getConsoleSink(),
},
loggers: [
{ category: ["logtape", "meta"], sinks: ["console"], lowestLevel: "error" },
{ category: ["my-app"], sinks: ["console"] , lowestLevel: "debug" },
],
});
const logger = getLogger(["my-app", "main"]);
logger.info`Hello world!`;
logger.debug`Value is ${42}`;
logger.warn`test Warning`;
logger.error`test Error`;
logger.fatal`test Fatal`;
</script>
Dev Web Tools will display all logs because the lowest level is defined as « debug » :

We can imagine add an async request to logs with an HTTP Post Request. Logs will be send to the console and to HTTP request to the URL ./Logs .
<script type="module">
import { configure, getLogger, getConsoleSink } from "https://esm.sh/@logtape/logtape";
import { fromAsyncSink } from "https://esm.sh/@logtape/logtape";
const webhookSink = async (record) => {
await fetch("./Logs", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
timestamp: record.timestamp,
level: record.level,
message: record.message,
properties: record.properties,
}),
});
};
await configure({
sinks: {
console: getConsoleSink(),
http: webhookSink,
},
loggers: [
{ category: ["logtape", "meta"], sinks: ["console"], lowestLevel: "error" },
{ category: ["my-app"], sinks: ["console","http"] , lowestLevel: "debug" },
],
});
const logger = getLogger(["my-app", "main"]);
logger.info`Hello world!`;
logger.debug`Value is ${42}`;
logger.warn`test Warning`;
logger.error`test Error`;
logger.fatal`test Fatal`;