---
title: Logging
description: Configurable logging.
plugin: log
i18nReady: true
---

import PluginLinks from '@components/PluginLinks.astro';
import Compatibility from '@components/plugins/Compatibility.astro';

import { Tabs, TabItem, Steps } from '@astrojs/starlight/components';
import CommandTabs from '@components/CommandTabs.astro';
import PluginPermissions from '@components/PluginPermissions.astro';

<PluginLinks plugin={frontmatter.plugin} />

Configurable logging for your Tauri app.

## Supported Platforms

<Compatibility plugin={frontmatter.plugin} />

## Setup

Install the log plugin to get started.

<Tabs>
  <TabItem label="Automatic" >

    Use your project's package manager to add the dependency:

    { ' ' }

    <CommandTabs
      npm="npm run tauri add log"
      yarn="yarn run tauri add log"
      pnpm="pnpm tauri add log"
      deno="deno task tauri add log"
      bun="bun tauri add log"
      cargo="cargo tauri add log"
    />

  </TabItem>
  <TabItem label = "Manual">
    <Steps>

    1. Run the following command in the `src-tauri` folder to add the plugin to the project's dependencies in `Cargo.toml`:

        ```sh frame=none
        cargo add tauri-plugin-log
        ```

    2.  Modify `lib.rs` to initialize the plugin:

        ```rust title="src-tauri/src/lib.rs" ins={4}
        #[cfg_attr(mobile, tauri::mobile_entry_point)]
        pub fn run() {
            tauri::Builder::default()
                .plugin(tauri_plugin_log::Builder::new().build())
                .run(tauri::generate_context!())
                .expect("error while running tauri application");
        }
        ```

    3.  Install the JavaScript Guest bindings using your preferred JavaScript package manager:

        <CommandTabs
          npm = "npm install @tauri-apps/plugin-log"
          yarn = "yarn add @tauri-apps/plugin-log"
          pnpm = "pnpm add @tauri-apps/plugin-log"
          deno = "deno add npm:@tauri-apps/plugin-log"
          bun = "bun add @tauri-apps/plugin-log"
        />

    </Steps>

  </TabItem>
</Tabs>

## Usage

  <Steps>

1.  First, you need to register the plugin with Tauri.

    ```rust title="src-tauri/src/lib.rs" {1} {6-14}
    use tauri_plugin_log::{Target, TargetKind};

    #[cfg_attr(mobile, tauri::mobile_entry_point)]
    pub fn run() {
        tauri::Builder::default()
            .plugin(tauri_plugin_log::Builder::new().build())
            .run(tauri::generate_context!())
            .expect("error while running tauri application");
    }
    ```

2.  Afterwards, all the plugin's APIs are available through the JavaScript guest bindings:

    ```javascript
    import {
      warn,
      debug,
      trace,
      info,
      error,
      attachConsole,
      attachLogger,
    } from '@tauri-apps/plugin-log';
    // when using `"withGlobalTauri": true`, you may use
    // const { warn, debug, trace, info, error, attachConsole, attachLogger } = window.__TAURI__.log;
    ```

  </Steps>

## Logging

<Tabs syncKey="lang">
  <TabItem label="JavaScript">
Use one of the plugin's `warn`, `debug`, `trace`, `info` or  `error` APIs to produce a log record from JavaScript code:

```js
import { warn, debug, trace, info, error } from '@tauri-apps/plugin-log';

trace('Trace');
info('Info');
error('Error');
```

To automatically forward all `console` messages to the log plugin you can rewrite them:

```ts
import { warn, debug, trace, info, error } from '@tauri-apps/plugin-log';

function forwardConsole(
  fnName: 'log' | 'debug' | 'info' | 'warn' | 'error',
  logger: (message: string) => Promise<void>
) {
  const original = console[fnName];
  console[fnName] = (message) => {
    original(message);
    logger(message);
  };
}

forwardConsole('log', trace);
forwardConsole('debug', debug);
forwardConsole('info', info);
forwardConsole('warn', warn);
forwardConsole('error', error);
```

</TabItem>

<TabItem label="Rust">
To create your own logs on the Rust side you can use the [`log` crate]:

```rust
log::error!("something bad happened!");
log::info!("Tauri is awesome!");
```

Note that the [`log` crate] must be added to your `Cargo.toml` file:

```toml
[dependencies]
log = "0.4"
```

</TabItem>
</Tabs>

## Log targets

The log plugin builder has a `targets` function that lets you configure common destination of all your application logs.

:::note
By default the plugin logs to stdout and to a file in the application logs directory.
To only use your own log targets, call `clear_targets`:

```rust
tauri_plugin_log::Builder::new()
.clear_targets()
.build()
```

:::

### Printing logs to the terminal

To forward all your logs to the terminal, enable the `Stdout` or `Stderr` targets:

```rust
tauri_plugin_log::Builder::new()
  .target(tauri_plugin_log::Target::new(
    tauri_plugin_log::TargetKind::Stdout,
  ))
  .build()
```

This target is enabled by default.

### Logging to the webview console

To view all your Rust logs in the webview console, enable the `Webview` target and run `attachConsole` in your frontend:

```rust
tauri_plugin_log::Builder::new()
  .target(tauri_plugin_log::Target::new(
    tauri_plugin_log::TargetKind::Webview,
  ))
  .build()
```

```js
import { attachConsole } from '@tauri-apps/plugin-log';
const detach = await attachConsole();
// call detach() if you do not want to print logs to the console anymore
```

### Persisting logs

To write all logs to a file, you can use either the `LogDir` or the `Folder` targets.

- `LogDir`:

```rust
tauri_plugin_log::Builder::new()
  .target(tauri_plugin_log::Target::new(
    tauri_plugin_log::TargetKind::LogDir {
      file_name: Some("logs".to_string()),
    },
  ))
  .build()
```

When using the LogDir target, all logs are stored in the recommended log directory.
The following table describes the location of the logs per platform:

| Platform | Value                                                                                    | Example                                           |
| -------- | ---------------------------------------------------------------------------------------- | ------------------------------------------------- |
| Linux    | `$XDG_DATA_HOME/{bundleIdentifier}/logs` or `$HOME/.local/share/{bundleIdentifier}/logs` | `/home/alice/.local/share/com.tauri.dev/logs`     |
| macOS    | `{homeDir}/Library/Logs/{bundleIdentifier}`                                              | `/Users/Alice/Library/Logs/com.tauri.dev`         |
| Windows  | `{FOLDERID_LocalAppData}/{bundleIdentifier}/logs`                                        | `C:\Users\Alice\AppData\Local\com.tauri.dev\logs` |

- `Folder`:

The Folder target lets you write logs to a custom location in the filesystem.

```rust
tauri_plugin_log::Builder::new()
  .target(tauri_plugin_log::Target::new(
    tauri_plugin_log::TargetKind::Folder {
      path: std::path::PathBuf::from("/path/to/logs"),
      file_name: None,
    },
  ))
  .build()
```

The default `file_name` is the application name.

#### Configuring log file behavior

By default the log file gets discarded when it reaches the maximum size.
The maximum file size can be configured via the builder's `max_file_size` function:

```rust
tauri_plugin_log::Builder::new()
  .max_file_size(50_000 /* bytes */)
  .build()
```

Tauri can automatically rotate your log file when it reaches the size limit instead of discarding the previous file.
This behavior can be configured using `rotation_strategy`:

```rust
tauri_plugin_log::Builder::new()
  .rotation_strategy(tauri_plugin_log::RotationStrategy::KeepAll)
  .build()
```

### Filtering

By default **all** logs are processed. There are some mechanisms to reduce the amount of logs and filter only relevant information.

### Maximum log level

To set a maximum log level, use the `level` function:

```rust
tauri_plugin_log::Builder::new()
  .level(log::LevelFilter::Info)
  .build()
```

In this example, debug and trace logs are discarded as they have a lower level than _info_.

It is also possible to define separate maximum levels for individual modules:

```rust
tauri_plugin_log::Builder::new()
  .level(log::LevelFilter::Info)
  // verbose logs only for the commands module
  .level_for("my_crate_name::commands", log::LevelFilter::Trace)
  .build()
```

Note that these APIs use the [`log` crate], which must be added to your `Cargo.toml` file:

```toml
[dependencies]
log = "0.4"
```

### Target filter

A `filter` function can be defined to discard unwanted logs by checking their metadata:

```rust
tauri_plugin_log::Builder::new()
  // exclude logs with target `"hyper"`
  .filter(|metadata| metadata.target() != "hyper")
  .build()
```

### Formatting

The log plugin formats each log record as `DATE[TARGET][LEVEL] MESSAGE`.
A custom format function can be provided with `format`:

```rust
tauri_plugin_log::Builder::new()
  .format(|out, message, record| {
    out.finish(format_args!(
      "[{} {}] {}",
      record.level(),
      record.target(),
      message
    ))
  })
  .build()
```

#### Log dates

By default the log plugin uses the UTC timezone to format dates
but you can configure it to use the local timezone with `timezone_strategy`:

```rust
tauri_plugin_log::Builder::new()
  .timezone_strategy(tauri_plugin_log::TimezoneStrategy::UseLocal)
  .build()
```

## Permissions

By default, all plugin commands are blocked and cannot be accessed.
You must define a list of permissions in your `capabilities` configuration.

See the [Capabilities Overview](/security/capabilities/) for more information and the [step by step guide](/learn/security/using-plugin-permissions/) to use plugin permissions.

```json title="src-tauri/capabilities/default.json" ins={6}
{
  "$schema": "../gen/schemas/desktop-schema.json",
  "identifier": "main-capability",
  "description": "Capability for the main window",
  "windows": ["main"],
  "permissions": ["log:default"]
}
```

<PluginPermissions plugin={frontmatter.plugin} />

[`log` crate]: https://crates.io/crates/log
