How do I utilize the file handler to execute the flush method within the Deno log module using Typescript?

I'm having trouble accessing the fileHandler object from my logger in order to flush the buffer to the file.

This is the program I am working with:

import * as log from "https://deno.land/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="5e2d2a3a1e6e70696b706e">[email protected]</a>/log/mod.ts"
import { Application } from "https://deno.land/x/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="a2cdc3c9e2d4948c918c93">[email protected]</a>/mod.ts";

const app   = new Application()
const port  = 7001

await log.setup({
    handlers:{
        file: new log.handlers.FileHandler("DEBUG",{
            filename: "logger.log",
            formatter: lr => {
                return `${lr.datetime.toISOString()} [${lr.levelName}] ${lr.msg}`
            }
        })
    },
    loggers: {
        default: {
            level: "DEBUG",
            handlers: ["file"]
        }
    }
})
const logger = log.getLogger()
logger.debug("hi there")

app.use((ctx) => {
    ctx.response.body = 'Hi there'
})

console.log(`listening on port ${port}`)
app.listen({ port })

The issue I'm facing is that the log message isn't being written to the file. If I remove the last line ( app.listen() ), it does write to the file because the process ends. However, if I leave it listening, the process never ends and the log buffer is never flushed.

Even when I interrupt the process with Ctrl-C, it still doesn't write to the file.

According to the documentation (https://deno.land/[email protected]/log/README.md), I can force a log flush using the flush method from FileHandler. But I'm uncertain about how to access the fileHandler object.
So, I have attempted the following:

const logger = log.getLogger()
logger.debug("hi there")
logger.handlers[0].flush()

Surprisingly, this works in JavaScript, but not in TypeScript.
In TypeScript, I get the following error:

error: TS2339 [ERROR]: Property 'flush' does not exist on type 'BaseHandler'.
logger.handlers[0].flush()

Answer №1

After some experimenting, I finally found a workaround.
To solve my issue, all I needed to do was import the FileHandler class and downgrade my handler from BaseHandler to FileHandler. I made sure to include this line in the list of imports:

import { FileHandler } from "https://deno.land/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="8025253031292c24022d31182124272c283b">[email protected]</a>/log/handlers.ts"

Then, right after setting up the logger:

logger.debug("hello there")
const fileHandler = <FileHandler> logger.handlers[0]
fileHandler.flush()

Although it might seem unconventional, this method did the trick for now. I believe there could be a more elegant solution out there, but this one gets the job done.

Answer №2

Recapping with Santi's insights.

From my experience, logs in a file work well in a program that ends naturally, like one that terminates on its own or with Deno.exit(0). Issues arise when dealing with never-ending loops. In such cases, logs may not be appended to their files. Here's a solution:

// dev.js : "I want my logs" example
import {serve} from "https://deno.land/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="d1a2a5b591e1ffe0e0e2ffe1">[email protected]</a>/http/server_legacy.ts";
import * as log from "https://deno.land/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="d3a0a7b793e3fde2e2e0fde3">[email protected]</a>/log/mod.ts";

// Simple setup from the official standard lib https://deno.land/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="1f6c6b7b5f2f312e2e2c312f">[email protected]</a>/log
await log.setup({
  handlers: {
    file: new log.handlers.FileHandler("WARNING", {
      filename: "./log.txt",
      formatter: "{levelName} {msg}",
    }),
  },
  loggers: {
    default: {
      level: "DEBUG",
      handlers: ["file"],
    },
  },
});

// Initialization
let logger;
logger = log.getLogger();
logger.warning('Started');  

const fileHandler = logger.handlers[0];
await fileHandler.flush(); // <---- Important to flush! Thanks to Santi

// Request loop
const srv = serve(`:4321`);
for await (const request of srv) {
  request.respond({body: 'Hello', status: 200});

  logger.warning('Hit !');
  fileHandler.flush();  // <---- Flush again
}

Run with

$ deno run -A dev.js

Check log.txt using:

$ curl localhost:4321

This method is basic and may introduce delays in the process. The next step could involve triggering a time event to flush periodically.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Attempting to retrieve the value from a nested table within a table row using Jquery

<tr role="row" class="odd"> <td style="background-color:white"> <table> <tbody> <tr data-row-id="22"> <td id="pid"><input type="checkbox" class="sub_chk" value="8843" data-id="22">< ...

Toggle the visibility of a hidden div by clicking a button

After spending several days working on this project, just when I thought it was perfect, I had to completely restructure the entire page. Now I'm feeling stuck and in need of some help. The issue is that I have three images with buttons underneath eac ...

Can orbit controls be tweened in three.js?

When utilizing the TWEEN function within three.js, I have noticed that it is mainly used for tweening objects. Although I can successfully tween the camera's position, I am looking to also tween the orbit control to mimic following a target while the ...

Issues with webpage responsiveness, width not adjusting correctly

Just completed coding my website and now I'm facing a new challenge. I am focusing on making it responsive for tablet screens (768px) starting with the header section, but for some reason, the modifications I make in the responsive.css file are not ta ...

The process of transferring information from a JSON API to TypeScript models

When working with my JSON API in my services, I need to pass the data to my models. What is the most efficient way to accomplish this task? Currently, I am following this process: import { Attachment } from '.'; export class Contact { id: nu ...

Confusing postback phenomena in ASP.NET web forms

I have developed a small script that successfully maintains the focused element during an async postback. However, I encountered an issue when tabbing through controls generated inside an asp:Repeater, where a full postback is unexpectedly triggered. Below ...

Is it possible to refresh data efficiently using web scraping tools, similar to how it

While researching web scraping in Python, I consistently found references to BeautifulSoup and Selenium as the primary tools for retrieving HTML and JavaScript content from websites. One thing that has eluded me is finding a method to automatically update ...

Utilizing icons with vuetify's v-select component: a guide

In the code snippet below, I am using a v-select element to display a list of items filled from an array: <v-select v-model="myModel" :items="users" chips :readonly="!item.Active" label="Required users to f ...

Generate a new JSON reply using the current response

I received a JSON response that contains values for week 1, week 2, week 3, and week 4 under the 'week' key, along with counts based on categories (meetingHash) and weeks. I attempted to merge this data using the .reduce method but without succes ...

Modify how the browser typically processes script tags as its default behavior

Most of us are familiar with the functionality of <script src="/something.js"></script>. This loads the specified file onto the page and executes the script contained within. Is there a way to modify how <script> elements are interpreted ...

Generate an interactive pie chart with visually appealing animations using jQuery, without any actual data

My task involves creating a pie chart to visually display different categories. However, the challenge is that the chart does not contain any data, ruling out options like Google charts or other data-driven chart makers. As a solution, I have turned the pi ...

Fade out effect in jQuery upon reloading the page

Is there anyone who can assist me with this issue? The following script snippet allows a user to delete records from a table connected to a mySQL database. <script type="text/javascript> $(document).ready(function(){ $('form.delete ...

Using AngularJS and D3 to create a custom directive that allows for multiple instances of D3 loading within Angular applications

After creating an angular directive for a d3 forced-directed graph and using the code provided here, I encountered some issues with multiple loads. The directive seemed to load six times each time it was initialized, causing performance problems. To addres ...

Converting objects into JSON format

I'm trying to transform an object that looks like this: { user[id]: 1, user[name]: 'Lorem', money: '15.00' } Into the following structure: { user: { id: 1, name: 'Lorem', }, money: ...

How can I stop a user from navigating through links or submitting forms using jQuery?

I'm exploring the idea of converting my website into a Single Page Application. One challenge I am facing is capturing the navigation process, for example: <a href="myData.php">Change My Data</a> When a user clicks on the "Change My Data ...

Transitioning images smoothly and responsively with jQuery, creating a beautiful

Hey there! I'm looking for some help with transforming this jQuery effect. Instead of having fixed sized images, I want to set the size in percentage (width:100%; height:auto) so they can be responsive. Any creative ideas or suggestions? <scri ...

Trouble obtaining output from chrome.tabs in browser console

Currently, I am experimenting with the browser's console and attempting to retrieve all the details of the active tabs. In order to do so, I open the browser's console and input the following: However, I encountered the following error: VM713:1 ...

Difficulty encountered while deploying a React application on Netlify

I followed the instructions on a Medium link to deploy my React application on Netlify: To set up the production mode, I utilized an express server for defining build scripts. After creating the build scripts on my local machine, I uploaded them to the Ne ...

NodeJS: Speed up your workflow by compressing video files

In my quest to enhance the performance of my application, I am seeking ways to compress images and videos to their smallest possible size without sacrificing quality. This process is known as lossless compression. While the imagemin package has proven eff ...

What is the best way to retrieve the present value of an input that belongs to an array of objects?

Struggling with populating an array with data and encountering a specific issue. 1 - Attempting to determine an index for each key in the array of objects, but encountering an error when a new input is added dynamically. The inputs are successfully added ...