# Initializing

The following steps are required for applications using the Glean SDK, but not libraries.

{{#include ../../../shared/blockquote-info.html}}

##### Note

> The `initialize` function _must_ be called, even if telemetry upload is disabled.
> Glean needs to perform maintenance tasks even when telemetry is disabled, and because Glean
> does this as part of its initialization, it is _required_ to always call the `initialize`
> function. Otherwise, Glean won't be able to clean up collected data, disable queuing of pre-init
> tasks, or perform other required operations.
>
> This does not apply to special builds where telemetry is disabled at build time. In that case, it is acceptable to not call `initialize` at all.

{{#include ../../../shared/blockquote-stop.html}}

##### Initialize Glean with the correct value for `uploadEnabled`!

> `Glean.initialize` must **always** be called with real values.
> Always pass the user preference, e.g. `Glean.initialize(upload=userSettings.telemetry_enabled)` or the equivalent for your application.
> Never call `Glean.initialize(upload=true)` if `true` is a placeholder value that later gets reset by `Glean.setUploadEnabled(false)`.
> Depending on the provided placeholder value, this might trigger the generation of new client ids or the submission of bogus [`deletion-request` pings](../../user/pings/deletion_request.md).

{{#include ../../../shared/tab_header.md}}

<div data-lang="Kotlin" class="tab">

{{#include ../../../shared/blockquote-info.html}}

##### Multiple processes support

> The Glean SDK does not support use across multiple processes, and must only be initialized on the application's main process. Initializing in other processes is a no-op.
> Additionally, Glean must be initialized on the main (UI) thread of the applications main process. Failure to do so will throw an `IllegalThreadStateException`.

An excellent place to initialize Glean is within the `onCreate` method of the class that extends Android's `Application` class.

```Kotlin
import org.mozilla.yourApplication.GleanMetrics.GleanBuildInfo
import org.mozilla.yourApplication.GleanMetrics.Pings

class SampleApplication : Application() {

    override fun onCreate() {
        super.onCreate()

        // If you have custom pings in your application, you must register them
        // using the following command. This command should be omitted for
        // applications not using custom pings.
        Glean.registerPings(Pings)

        // Initialize the Glean library.
        Glean.initialize(
            applicationContext,
            // Here, `settings()` is a method to get user preferences, specific to
            // your application and not part of the Glean SDK API.
            uploadEnabled = settings().isTelemetryEnabled,
            buildInfo = GleanBuildInfo.buildInfo
        )
    }
}
```

The Glean SDK should be initialized as soon as possible, and importantly, before any other libraries in the application start using Glean.
Library code should never call `Glean.initialize`, since it should be called exactly once per application.

{{#include ../../../shared/blockquote-warning.html}}

##### Uploads when using Android Components

> When the Glean SDK is consumed through Android Components, it is required to configure an HTTP client to be used for upload.
> For example:
>
> ```Kotlin
> // Requires `org.mozilla.components:concept-fetch`
> import mozilla.components.concept.fetch.Client
> // Requires `org.mozilla.components:lib-fetch-httpurlconnection`.
> // This can be replaced by other implementations, e.g. `lib-fetch-okhttp`
> // or an implementation from `browser-engine-gecko`.
> import mozilla.components.lib.fetch.httpurlconnection.HttpURLConnectionClient
>
> import mozilla.components.service.glean.config.Configuration
> import mozilla.components.service.glean.net.ConceptFetchHttpUploader
>
> val httpClient = ConceptFetchHttpUploader(lazy { HttpURLConnectionClient() as Client })
> val config = Configuration(httpClient = httpClient)
> Glean.initialize(
>    context,
>    uploadEnabled = true,
>    configuration = config,
>    buildInfo = GleanBuildInfo.buildInfo
>)
>```

</div>

<div data-lang="Swift" class="tab">

{{#include ../../../shared/blockquote-info.html}}

##### Multiple processes support

> The Glean SDK does not support use across multiple processes, and must only be initialized on the application's main process.

An excellent place to initialize Glean is within the `application(_:)` method of the class that extends the `UIApplicationDelegate` class.

```Swift
import Glean
import UIKit

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
    func application(_: UIApplication, didFinishLaunchingWithOptions _: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // If you have custom pings in your application, you must register them
        // using the following command. This command should be omitted for
        // applications not using custom pings.
        Glean.shared.registerPings(GleanMetrics.Pings)

        // Initialize the Glean library.
        Glean.shared.initialize(
            // Here, `Settings` is a method to get user preferences specific to
            // your application, and not part of the Glean SDK API.
            uploadEnabled = Settings.isTelemetryEnabled
        )
    }
}
```

The Glean SDK should be initialized as soon as possible, and importantly, before any other libraries in the application start using Glean.
Library code should never call `Glean.shared.initialize`, since it should be called exactly once per application.

</div>

<div data-lang="Python" class="tab">

The main control for the Glean SDK is on the `glean.Glean` singleton.

The Glean SDK should be initialized as soon as possible, and importantly, before any other libraries in the application start using Glean.
Library code should never call `Glean.initialize`, since it should be called exactly once per application.


```python
from glean import Glean

Glean.initialize(
    application_id="my-app-id",
    application_version="0.1.0",
    upload_enabled=True,
)
```

Additional configuration is available on the `glean.Configuration` object, which can be passed into `Glean.initialize()`.

Unlike Android and Swift, the Python bindings do not automatically send any pings.
See the [custom pings documentation](../../user/pings/custom.md) about adding custom pings and sending them.

</div>

<div data-lang="Javascript" class="tab">

The main control for Glean is on the `Glean` singleton.

The Glean.js library should be initialized as soon as possible when the product using it is started.

```js
// Glean.js for webextensions: the following code
// runs in the background script.
import Glean from "@mozilla/glean/webext";

Glean.initialize(
    "my-app-id",
    true, // uploadEnabled
    {
      appDisplayVersion: "0.1.0"
    }
);
```
</div>

{{#include ../../../shared/tab_footer.md}}

## What happens after Glean is initialized?

Once initialized, if upload is enabled, the Glean SDK will automatically start collecting [baseline metrics](../../user/pings/metrics.md).
If upload is disabled, any persisted metrics, events and pings (other than `first_run_date` and `first_run_hour`) are cleared, and subsequent calls to record metrics will be no-ops.

## Release channels

If the application has the concept of release channels and knows which channel it is on at run-time,
then it can provide the Glean SDK with this information by setting it as part of the `Configuration` object parameter of the `initialize` method.

## Behavior when uninitialized

Metric recording that happens before the Glean SDK is initialized is queued and applied at initialization.
To avoid unbounded memory growth the queue is bounded (currently to a maximum of 100 tasks), and further recordings are dropped.
The number of recordings dropped, if any, is recorded in the `glean.error.preinit_tasks_overflow` metric.

Custom ping submission will not fail before initialization.
Collection and upload of the custom ping is delayed until the Glean SDK is initialized.
Built-in pings are only available after initialization.
