# `Oban.Plugin`
[🔗](https://github.com/oban-bg/oban/blob/v2.24.2/lib/oban/plugin.ex#L1)

Defines a shared behaviour for Oban plugins.

In addition to implementing the Plugin behaviour, all plugins **must** be a `GenServer`, `Agent`, or
another OTP compliant module.

## Example

Defining a basic plugin that satisfies the minimum behaviour:

    defmodule MyPlugin do
      @behaviour Oban.Plugin

      use GenServer

      @impl Oban.Plugin
      def start_link(opts) do
        GenServer.start_link(__MODULE__, opts, name: opts[:name])
      end

      @impl Oban.Plugin
      def validate(opts) do
        if is_atom(opts[:mode]) do
          :ok
        else
          {:error, "expected opts to have a :mode key"}
        end
      end

      @impl GenServer
      def init(opts) do
        case validate(opts) do
          :ok -> {:ok, opts}
          {:error, reason} -> {:stop, reason}
        end
      end
    end

# `option`

```elixir
@type option() ::
  {:conf, Oban.Config.t()} | {:name, GenServer.name()} | {atom(), term()}
```

# `format_logger_output`
*optional* 

```elixir
@callback format_logger_output(Oban.Config.t(), map()) :: map()
```

Format telemetry event meta emitted by the for inclusion in the default logger.

# `start_link`

```elixir
@callback start_link([option()]) :: GenServer.on_start()
```

Starts a Plugin process linked to the current process.

Plugins are typically started as part of an Oban supervision tree and will receive the current
configuration as `:conf`, along with a `:name` and any other provided options.

# `validate`

```elixir
@callback validate([option()]) :: :ok | {:error, String.t()}
```

Validate the structure, presence, or values of keyword options.

