# Example: Using with azure-functions-scaffold

This example shows how `azure-functions-logging` integrates with projects generated by
[azure-functions-scaffold](https://github.com/yeongseon/azure-functions-scaffold).

## Overview

Every project created with `afs new` includes `azure-functions-logging` as a default
dependency and generates `app/core/logging.py` with a ready-to-use configuration.
No extra flags or setup steps are required.

## Generated Project Layout

```text
my-api/
  app/
    core/
      logging.py      ← configure_logging() + module logger
    functions/
      http.py
  function_app.py     ← calls configure_logging() at startup
  pyproject.toml      ← azure-functions-logging listed under [project.dependencies]
```

## Generated Files

### `app/core/logging.py`

```python
from __future__ import annotations

from azure_functions_logging import get_logger, setup_logging


def configure_logging() -> None:
    """Configure structured logging for the Azure Functions application."""
    setup_logging(format="json")


logger = get_logger("my-api")
```

### `function_app.py` (startup call)

```python
from __future__ import annotations

import azure.functions as func

from app.core.logging import configure_logging
from app.functions.http import http_blueprint

configure_logging()

app = func.FunctionApp()
app.register_functions(http_blueprint)
```

## Using the Logger in Function Modules

Import the pre-created logger from `app.core.logging` in any function module.

```python
from __future__ import annotations

import azure.functions as func

from app.core.logging import logger

http_blueprint = func.Blueprint()


@http_blueprint.route(route="hello", methods=["GET"], auth_level=func.AuthLevel.ANONYMOUS)
def hello(req: func.HttpRequest) -> func.HttpResponse:
    name = req.params.get("name", "world")
    logger.info("hello invoked", name=name)
    return func.HttpResponse(f"Hello, {name}!")
```

## Injecting Invocation Context

Pass the `context` parameter to `inject_context()` so that invocation ID and function
name are attached to every log record automatically.

```python
from __future__ import annotations

import azure.functions as func

from azure_functions_logging import inject_context

from app.core.logging import logger

http_blueprint = func.Blueprint()


@http_blueprint.route(route="hello", methods=["GET"], auth_level=func.AuthLevel.ANONYMOUS)
def hello(req: func.HttpRequest, context: func.Context) -> func.HttpResponse:
    inject_context(context)
    name = req.params.get("name", "world")
    logger.info("hello invoked", name=name)
    return func.HttpResponse(f"Hello, {name}!")
```

JSON output in Azure Monitor will include `invocation_id` and `function_name` fields.

## Customising Log Level per Environment

Override the level at startup without touching the generated file.

```python
# function_app.py
import logging

from azure_functions_logging import setup_logging

setup_logging(level=logging.DEBUG, format="json")
```

Or keep `format="color"` locally and switch to `"json"` in production via an environment
variable.

```python
import logging
import os

from azure_functions_logging import setup_logging

log_format = os.environ.get("LOG_FORMAT", "json")
log_level = logging.DEBUG if os.environ.get("DEBUG") else logging.INFO

setup_logging(level=log_level, format=log_format)  # type: ignore[arg-type]
```

## Scaffolding a New Project

```bash
pip install azure-functions-scaffold

# Create a project — logging is included by default
afs new my-api

# With additional integrations
afs new my-api --with-openapi --with-validation --with-doctor
```

## Why This Pattern Works

- `setup_logging()` runs once before any function registers, so all blueprints share
  the same configuration.
- `get_logger("my-api")` gives a stable named logger scoped to the application, not the
  module path, which avoids naming conflicts across blueprints.
- JSON format is the default because Azure Monitor ingests structured fields directly,
  enabling rich Kusto queries without text parsing.

## Related Examples

- [Basic Setup](basic_setup.md)
- [Context Injection](context_injection.md)
- [JSON Output](json_output.md)
- [Context Binding](context_binding.md)
