Anatomy of a Vercel Log Entry

Logalert gives you alerts based on specific keywords in your Vercel logs. When users encounter errors, you can get notified via email and fix issues faster.

Vercel logs have a defined structure. When you are setting up your alert, you can choose how the alert will filter for log entries based on matches in specific fields the log entries.

Logs are represented in JSON form like this:

{
    "id": identifier,
    "message": text,
    "timestamp": timestamp,
    "requestId": identifier of request only on runtime logs,
    "statusCode": HTTP status code of request only on runtime logs,
    "source": "build", "static", "external", or "lambda",
    "projectId": identifier of project,
    "deploymentId": identifier of deployement,
    "buildId": identifier of build only on build logs,
    "destination": origin of external content only on external logs,
    "host": hostname,
    "path": path,
    "proxy": {
      "timestamp": timestamp of proxy request,
      "method": method of request,
      "scheme": protocol of request,
      "host": hostname,
      "path": path of proxy request,
      "userAgent": user agent,
      "referer": referer,
      "statusCode": HTTP status code of proxy request,
      "clientIp": client IP,
      "region": region request is processed,
      "cacheId": original request id when request is served from cache,
    }
  }

Each request to your website will emit one log entry in the above form. If you have serverless functions that print messages to stdout (console.log) or stderr (console.error) all output lines from one run of a serverless function will be aggregated into one log entry.

Let's dive a bit deeper into the most important fields of the log entry:

message

Logalert allows you to create alerts based on keywords in the log message field. The message field contains the outputs to stdout (console.log) or stderr (console.error).

If you are not printing to console, this field will likely be blank.

For backend serverless functions, all lines output from one serverless function request will be aggregated into one log entry. For example, if you are using Next.js and you have a serverless function defined in /pages/api/hello.js like so:

export default function handler(req, res) {
    console.log("line1")
    console.error("line2")
    return res.status(200).json({message:"OK"})
}

The log entry for a single request to this endpoint will look like the following (simplified):

{
    "message": "
        2021-07-26T16:34:09.512Z	INFO	line1
        2021-07-26T16:34:09.654Z	INFO	line2
    ",
    ...
}

Notice that both lines appear in the same log message, since they were printed in one single function call. Note that console.error does not emit as ERROR, rather it is recorded as INFO. This is a quirk of Vercel's logging system. (We have raised this issue with Vercel, and they say that this is intentional.)

Therefore, if you want Logalert to pick up the "error" keyword, it is not enough to use console.error. You must explicitly print the word "error" somewhere in your message.

// this will NOT trigger alert with keyword "error"

console.error("Invalid API Key")

// this WILL trigger alert with keyword "error"

console.error("Error: Invalid API Key")

statusCode vs. proxy.statusCode

The statusCode and the proxy.statusCode fields differ in that statusCode is the status code of the underlying server function while proxy.statusCode is the status code that your end user or client gets back as a response to their request.

For example, if you have a bug in your code that causes a serverless function to crash, statusCode might appear as -1 while proxy.statusCode would be 500.

Logalert allows you to create alerts based on the proxy.statusCode field because this is the status code that the client / end user will experience.

path vs. proxy.path

The path and the proxy.path fields differ in that path is the path of the file (for example in Next.js: /pages/api/[itemId]) whereas proxy.path is the path that the end user / client has requested. (for example in Next.js: /pages/api/abc234)

For example, if you are using Next.js and you have a serverless function defined in /pages/api/info/[itemId].js, the path and the proxy.path fields in your Vercel log entry would look like:

{
    "path": "/pages/api/info/[itemId]",
    "proxy": {
        "path": "/pages/api/info/1a2b3c4"
    }
    ...
}

Logalert allows you to create alerts based on the proxy.path field because this is the status code that the client / end user will experience. Please let us know if you would like to create alerts based a filter on the log entry's path field.

source

The source field can take on one of 4 values: "build", "static", "external", or "lambda". By default Logalert will monitor all four sources of logs. Therefore, you will likely not need to add a filter for the source field.

source="build" logs are logs emitted when you push a new deployment to Vercel, prompting a new build. Unlike logs from a user request (which are source="lambda" logs), each line in your build logs correspond to one log entry.

For example, the following 7 lines of build logs would emit 7 log entries!

19:20:38.109 Cloning github.com/your/repo (Branch: main, Commit: 01e3ba5)

19:20:39.017 Cloning completed: 908.165ms

19:20:39.038 Analyzing source code...

19:20:40.061 Installing build runtime...

19:20:41.899 Build runtime installed: 1.838s

19:20:44.279 Looking up build cache...

19:20:44.411 Build cache found. Downloading...

The first two entries would look like this:

[
    {
        message: "Cloning github.com/your/repo (Branch: main, Commit: 01e3ba5)",
        source: "build",
        ...
    },
    {
        message: "Cloning completed: 908.165ms",
        source: "build",
        ...
    },
    ...
];

source="static" logs are logs emitted when a request is made to a static resource hosted by your Vercel site. For example, if you are using Next.js, each request to images in your /public folder would emit one log message with source="static". Although static logs can produce a significant number of log entries, the message fields are usually empty and this is not a significant source of interest for your alerts.

source="external" logs are logs emitted when Vercel directs the response to an external service like AWS. As far as we can tell, these are used for media caching and do not constitute a significant source of logs or messages of interest for alerts.

source="lambda" logs are logs emitted for requests to your serverless functions. If you are using Next.js, each request to endpoints defined in /pages or /pages/api will emit a single log entry. These log entries will have the most interesting log message fields since these requests directly execute your code.

For more information about the format of a log entry, please refer to the Vercel API Documentation on logs.

Logalert alerts you when logs match filters based on the above fields. If you have any questions please contact us at support@logalert.app or leave us a message in the feedback form inside the app.