---
title: log_fastly
summary: Implementation of the log logging façade for Fastly Compute.
url: https://www.fastly.com/documentation/reference/compute/sdks/rust/log_fastly/
---

**Kind:** Module  
**Package:** log-fastly 0.13.1  
**Path:** `log_fastly`

Implementation of the [`log`](https://docs.rs/log/0.4.28/log/index.html) logging façade for Fastly Compute.

With this logger configured, [`log`'s logging statements](https://docs.rs/log#use) will send log messages to
your chosen [Real-Time Log Streaming](https://docs.fastly.com/en/guides/about-fastlys-realtime-log-streaming-features) endpoints. You should initialize the logger as soon
as your program starts. Logging statements will not do anything before initialization.

See the [Fastly
documentation](https://docs.fastly.com/en/guides/integrations#_logging-endpoints) for more
information about configuring logging endpoints for your service.

## Getting started

All you need to get started is your endpoint name and the level of log messages you want to
emit. For example, if you have an endpoint called `my_endpoint`, and you only want to emit log
messages at the "Warn" or "Error" level, you can use [`init_simple()`](https://www.fastly.com/documentation/reference/compute/sdks/rust/log_fastly/fn.init_simple/):

```rust
log_fastly::init_simple("my_endpoint", log::LevelFilter::Warn);
log::warn!("This will be written to my_endpoint...");
log::info!("...but this won't");
```

## Advanced configuration

For more precise control, including multiple endpoints and default endpoints for different
logging levels, use the [`Builder`](https://www.fastly.com/documentation/reference/compute/sdks/rust/log_fastly/struct.Builder/) interface. The first example is equivalent to:

```rust
log_fastly::Logger::builder()
    .max_level(log::LevelFilter::Warn)
    .default_endpoint("my_endpoint")
    .init();
```

The [`Builder::max_level()`](https://www.fastly.com/documentation/reference/compute/sdks/rust/log_fastly/struct.Builder/#method-max_level) option sets the most verbose level of logging that will be
emitted. Logging statements above that level, like `log::info!()` in the first example, will do
nothing.

**Note:** The default level is `LevelFilter::Off`, which emits no logging at all. You'll want to
change this for most configurations.

[`Builder::default_endpoint()`](https://www.fastly.com/documentation/reference/compute/sdks/rust/log_fastly/struct.Builder/#method-default_endpoint) sets the endpoint used whenever a logging statement is called
without a `target` field to specify its endpoint. With the default endpoint set to
`my_endpoint`, the logging statements in the first example are equivalent to:

```rust
log::warn!(target: "my_endpoint", "This will be written to my_endpoint...");
log::info!(target: "my_endpoint", "...but this won't");
```

### Use with Compute Log Tailing

[Compute Log Tailing](https://www.fastly.com/blog/introducing-compute-edge-log-tailing-for-better-observability-and-easier-debugging) is helpful for getting debugging output quickly from a
Compute program under development by capturing output from `stdout` or `stderr`. To
configure logging to output to `stdout` or `stderr` in addition to the specified log endpoint,
enable echoing when building the logger:

```rust
log_fastly::Logger::builder()
    .max_level(log::LevelFilter::Warn)
    .default_endpoint("my_endpoint")
    .echo_stdout(true)
    .init();
```

### Multiple endpoints

Setting an endpoint as the default will automatically register it for use with the logger, but
you can register additional endpoints with [`Builder::endpoint()`](https://www.fastly.com/documentation/reference/compute/sdks/rust/log_fastly/struct.Builder/#method-endpoint):

```rust
log_fastly::Logger::builder()
    .max_level(log::LevelFilter::Warn)
    .default_endpoint("my_endpoint")
    .endpoint("my_other_endpoint")
    .init();
log::warn!(target: "my_endpoint", "This will be written to my_endpoint...");
log::warn!(target: "my_other_endpoint", "...but this will be written to my_other_endpoint");
```

### Per-endpoint logging levels

You can also set a per-endpoint logging level, though levels higher than `max_level` are always
ignored:

```rust
log_fastly::Logger::builder()
    .max_level(log::LevelFilter::Warn)
    .default_endpoint("my_endpoint")
    .endpoint_level("my_other_endpoint", log::LevelFilter::Trace)
    .endpoint_level("error_only", log::LevelFilter::Error)
    .init();
log::warn!(target: "my_other_endpoint", "This will be written to my_other_endpoint...");
log::trace!(target: "my_other_endpoint", "...but this won't, because max_level wins");
log::error!(target: "error_only", "This will be written to error_only...");
log::warn!(target: "error_only", "...but this won't, because the endpoint's level is lower");
```

### Per-level default endpoints

In the previous examples, the same endpoint is set as the default for all logging levels. You
can also specify default endpoints for individual levels using
[`Builder::default_level_endpoint()`](https://www.fastly.com/documentation/reference/compute/sdks/rust/log_fastly/struct.Builder/#method-default_level_endpoint). The defaults are combined in order, so you can specify an
overall default endpoint, and then as many level-specific endpoints as you need:

```rust
log_fastly::Logger::builder()
    .max_level(log::LevelFilter::Info)
    .default_endpoint("my_endpoint")
    .default_level_endpoint("error_only", log::Level::Error)
    .init();
log::info!("This will be written to my_endpoint...");
log::warn!(".. and this will too.");
log::error!("But this will be written to error_only");
```

### Module name filters

In addition to per-endpoint logging levels, you can set logging levels based on the name of the
Rust module that contains the logging statement.

No filtering is done based on the module name by default, but if any module name patterns are
specified, only log statements that match one of the patterns will be emitted. For example, if
your application is a crate called `my_app`, you can filter out any messages other than
`my_app`'s :

```rust
log_fastly::Logger::builder()
    .max_level(log::LevelFilter::Info)
    .default_endpoint("my_endpoint")
    .filter_module("my_app", log::LevelFilter::Warn)
    .init();
log::warn!("This will be written to my_endpoint");
// This won't emit any log messages, because no patterns match `some_dependency`
some_dependency::function_that_logs();
```

The filter expressions support the full syntax of the [`regex`](https://docs.rs/regex#syntax) crate. This is
particularly useful if your patterns overlap, but you'd like to still treat them distinctly. For
example, suppose you want to set the log level of the module `my_app::my_module` to be more
restrictive than the top level `my_app` module. You can use `$` to make sure the
less-restrictive pattern matches to the end of the module name, instead of matching any module
name that contains `my_app`:

```rust
mod my_module {
    pub fn do_a_thing() {
        log::warn!("This won't be written, because this module's max level is Error");
    }
}
log_fastly::Logger::builder()
    .max_level(log::LevelFilter::Info)
    .default_endpoint("my_endpoint")
    .filter_module("my_app$", log::LevelFilter::Warn)
    .filter_module("my_app::my_module", log::LevelFilter::Error)
    .init();
log::warn!("This will be written to my_endpoint");
// This won't emit any log messages, because "my_app$" doesn't match, and "my_app::my_module"
// is limited to Error
my_module::do_a_thing();
```

## Registering endpoints

All endpoints used by your logging statements must be registered when the logger is created. The
following functions automatically register an endpoint if it is not already registered.

- [`init_simple()`](https://www.fastly.com/documentation/reference/compute/sdks/rust/log_fastly/fn.init_simple/)
- [`Builder::endpoint()`](https://www.fastly.com/documentation/reference/compute/sdks/rust/log_fastly/struct.Builder/#method-endpoint)
- [`Builder::endpoint_level()`](https://www.fastly.com/documentation/reference/compute/sdks/rust/log_fastly/struct.Builder/#method-endpoint_level)
- [`Builder::default_endpoint()`](https://www.fastly.com/documentation/reference/compute/sdks/rust/log_fastly/struct.Builder/#method-default_endpoint)
- [`Builder::default_level_endpoint()`](https://www.fastly.com/documentation/reference/compute/sdks/rust/log_fastly/struct.Builder/#method-default_level_endpoint)

You can pass the endpoint name as a string, or an explicit [`fastly::log::Endpoint`](https://docs.rs/fastly/latest/fastly/log/struct.Endpoint.html) value. The
following examples are equivalent:

```rust
log_fastly::init_simple("my_endpoint", log::LevelFilter::Info);
```

```rust
log_fastly::init_simple(
    fastly::log::Endpoint::from_name("my_endpoint"),
    log::LevelFilter::Info,
);
```

If a logging statement uses `target: "my_endpoint"` but `my_endpoint` is not registered, the
message will be logged to the default endpoint for that level, if one exists.

## Endpoint and module name collisions

Due to a [limitation of `log`](https://github.com/rust-lang/log/issues/390), logging from a module with the same name as one of
your endpoints will cause logs to be sent to that endpoint, even if no `target` is specified,
and the endpoint is not a default. For example, if you have an endpoint named `my_app`, and your
application is a crate also called `my_app`:

```rust
log_fastly::Logger::builder()
    .max_level(log::LevelFilter::Info)
    .default_endpoint("my_endpoint")
    .endpoint("my_app")
    .init();
log::info!("This will be written to my_app, even though my_endpoint is the default");
log::info!(
    target: "my_endpoint",
    "This will be written to my_endpoint, because the target is explicit",
);
```

We hope to address this issue in future releases, but the current workarounds are to either make
sure your endpoint names and crate name are distinct, or use the explicit target syntax whenever
logging from your top-level module.

## Structs

| Name | Summary |
| --- | --- |
| [Builder](https://www.fastly.com/documentation/reference/compute/sdks/rust/log_fastly/struct.Builder/) | A builder type for [`Logger`](https://www.fastly.com/documentation/reference/compute/sdks/rust/log_fastly/struct.Logger/). |
| [Logger](https://www.fastly.com/documentation/reference/compute/sdks/rust/log_fastly/struct.Logger/) | An implementation of the [`log::Log`](https://docs.rs/log/0.4.28/log/trait.Log.html) trait for Fastly Compute. |

## Functions

| Name | Summary |
| --- | --- |
| [init_simple](https://www.fastly.com/documentation/reference/compute/sdks/rust/log_fastly/fn.init_simple/) | Initialize logging with a single endpoint filtered by log level. |
