# JavaScript advanced usage

Get started with Logtail in your JavaScript application using this overview of the Logtail logger.

[info]
**New to logging?** See the [Intro guide to Node.js logging](https://betterstack.com/community/guides/logging/how-to-start-logging-with-node-js/) and the [Best practices for logging in Node.js](https://betterstack.com/community/guides/logging/nodejs-logging-best-practices/).

**Not using Logtail yet?** Check out the [Quick start guide](https://betterstack.com/docs/logs/javascript/install/) to install and set up the Logtail JavaScript client. 
[/info]

## Log levels

Logtail JavaScript client instance provides 4 logging methods for the 4 default log levels. The log levels and their methods are:

- **DEBUG** - Send debug messages with `debug()`
- **INFO** - Keep track of your app's progress with `info()`
- **WARN** - Report non-critical issues with `warn()`
- **ERROR** - Log serious problems with `error()`

## Logging example

To send a log message of selected log level, use the corresponding method. In this example, we send the **DEBUG** level log and **ERROR** level log:

```javascript
[label Send logs to Logtail]
// Send DEBUG level log using the debug() method
logtail.debug("I am using Logtail!");

// Send ERROR level log using the error() method
logtail.error("Oops! An runtime ERROR occurred!");
```

The Logtail client automatically adds context to the logs.  
The following JSON output is sent to Logtail:

```json
[output]
{
   "dt":"2022-02-01 12:01:10.127 UTC",
   "context":{
      "runtime":{
         "column_integer":"21",
         "file_string":"node_modules/@logtail/core/dist/cjs/base.js",
         "line_integer":"141",
         "type_string":"Node",
         "function_string":"debug",
         "method_string":"debug"
      },
      "system":{
         "main_file_string":"/mnt/d/js_logtail/index.js",
         "pid_integer":"4193"
      }
   },
   "level_string":"debug",
   "message_string":"I am using Logtail!"
}

{
   "dt":"2022-02-01 12:01:10.127 UTC",
   "context":{
      "runtime":{
         "column_integer":"8",
         "file_string":"index.js",
         "line_integer":"40",
         "type_string":"Object"
      },
      "system":{
         "main_file_string":"/mnt/d/js_logtail/index.js",
         "pid_integer":"4193"
      }
   },
   "level_string":"error",
   "message_string":"Oops! A runtime ERROR occurred!"
}

```

## Logging structured data

Quickly troubleshoot your application by logging structured data.
Pass an object as a second argument to any logging method, like in the example below:

```javascript
[label Send structured logs to Logtail]
logtail.warn("Something is not quite right.", {
    user: {
        username: "John Doe",
        email: "john@example.com"
    },
    additional_info: {
        tried_accessing: "/url/of/error"
    }
});
```

This creates the following JSON output:

```json
[output]
{
   "dt":"2022-02-01 12:01:10.127 UTC",
   "context":{
      "runtime":{
         "column_integer":"8",
         "file_string":"index.js",
         "line_integer":"29",
         "type_string":"Object"
      },
      "system":{
         "main_file_string":"/mnt/d/js_logtail/index.js",
         "pid_integer":"4193"
      }
   },
   "level_string":"warn",
   "message_string":"Something is not quite right.",
   "additional_info":{
      "tried_accessing_string":"/url/of/error"
   },
   "user":{
      "email_string":"someuser@example.com",
      "username_string":"someuser"
   }
}
```

## Middleware

You can intercept every logged item and modify it before it's pushed to Logtail. This could be useful, for example, for adding the current user's ID to the log or for filtering:

[code-tabs]
```js
[label Enrich logs]
// Intercept the log and add userId to the content
async function enrichLogs(log) {
    return {
        ...log,
        userId: getCurrentUserId()
    };
}

// Tell Logtail client to use the enriching function
logtail.use(enrichLogs);
```
```js
[label Filter logs]
// Ignore any log with "[ignore]" in its message
async function filterLogs(log) {
    const shouldIgnore = log.message?.includes("[ignore]");
    return shouldIgnore ? null : log;
}

// Tell Logtail client to use the filtering function
logtail.use(filterLogs);
```
[/code-tabs]

### TypeScript

If you're using Logtail in a TypeScript codebase, you can take advantage of our types. You could write the enriching middleware function with types like this:

```javascript
[label Enrich logs in TypeScript]
import { ILogtailLog } from "@logtail/types";

async function enrichLogs(log: ILogtailLog): Promise<ILogtailLog> {
    return {
        ...log,
        userId: getCurrentUserId()
    };
}
```