Azure Log Integration :: Kloudfuse Docs

Azure Log Integration

Kloudfuse ingests Azure logs by routing them through an Azure Event Hub and a custom Azure Function App that forwards records to the Kloudfuse HTTP ingestion endpoint.

For an overview of how this fits into the broader Azure integration architecture, see Azure Integration Architecture.

Overview

Azure resources emit two categories of logs:

Both categories are routed through the same pipeline:

  1. Azure Diagnostic Settings forward logs from each resource to an Azure Event Hub Namespace.

  2. An Azure Function App with an Event Hub trigger reads each batch of events and forwards them to the Kloudfuse logs ingestion endpoint over HTTPS.

  3. Logs appear in the Kloudfuse Log Analytics interface within seconds.

Common use cases:

Prerequisites

Step 1: Create an Event Hub Namespace and Hub

An Event Hub Namespace is the container for one or more Event Hubs. Create a dedicated namespace and hub for Kloudfuse log ingestion.

Create the Namespace

az eventhubs namespace create \
  --name kloudfuse-logs \
  --resource-group <resource-group> \
  --location <region> \
  --sku Standard

Create the Event Hub

az eventhubs eventhub create \
  --name kloudfuse \
  --namespace-name kloudfuse-logs \
  --resource-group <resource-group> \
  --partition-count 4 \
  --message-retention 1

Create a Shared Access Policy

Create a policy that allows both sending (for Diagnostic Settings) and listening (for the Function App):

az eventhubs namespace authorization-rule create \
  --name kloudfuse-policy \
  --namespace-name kloudfuse-logs \
  --resource-group <resource-group> \
  --rights Listen Send

Retrieve the connection string — you will need this when configuring the Function App:

az eventhubs namespace authorization-rule keys list \
  --name kloudfuse-policy \
  --namespace-name kloudfuse-logs \
  --resource-group <resource-group> \
  --query primaryConnectionString \
  --output tsv

Save the output as EVENT_HUB_CONNECTION_STRING.

Step 2: Create an Azure Function App

The Function App reads events from the Event Hub and forwards them to Kloudfuse.

Create the Function App

Create a storage account (required by Function Apps) and the Function App itself. Both names must be globally unique in Azure:

az storage account create \
  --name <storage-account-name> \
  --resource-group <resource-group> \
  --location <region> \
  --sku Standard_LRS

az functionapp create \
  --name <function-app-name> \
  --resource-group <resource-group> \
  --storage-account <storage-account-name> \
  --consumption-plan-location <region> \
  --runtime node \
  --runtime-version 18 \
  --functions-version 4 \
  --os-type Linux

Configure Application Settings

Set the Event Hub connection string and the Kloudfuse credentials as application settings:

az functionapp config appsettings set \
  --name <function-app-name> \
  --resource-group <resource-group> \
  --settings \
    "EventHubConnection=<EVENT_HUB_CONNECTION_STRING>" \
    "KF_API_KEY=<your-kloudfuse-api-key>" \
    "KF_URL=<your-kloudfuse-hostname>"

Replace <your-kloudfuse-hostname> with the hostname of your Kloudfuse instance only — no https:// prefix and no trailing slash, for example kloudfuse.example.com. The forwarder constructs the HTTPS connection internally using the hostname.

Deploy the Function Code

Create the function directory structure and deploy the forwarding function:

mkdir -p kloudfuse-azure-fn/kloudfuse-log-forwarder
cd kloudfuse-azure-fn

Create host.json:

{
  "version": "2.0",
  "logging": {
    "applicationInsights": {
      "samplingSettings": {
        "isEnabled": true,
        "excludedTypes": "Request"
      }
    }
  }
}

Create kloudfuse-log-forwarder/function.json:

{
  "bindings": [
    {
      "type": "eventHubTrigger",
      "name": "eventHubMessages",
      "direction": "in",
      "eventHubName": "kloudfuse",
      "connection": "EventHubConnection",
      "cardinality": "many",
      "dataType": ""
    }
  ]
}

Create kloudfuse-log-forwarder/index.js:

const https = require("https");

const KF_API_KEY = process.env.KF_API_KEY || "";
const KF_URL     = process.env.KF_URL     || "";  // hostname only, e.g. kloudfuse.example.com

module.exports = async function (context, eventHubMessages) {
  const messages = Array.isArray(eventHubMessages)
    ? eventHubMessages
    : [eventHubMessages];

// Normalise each message to a parsed object, then wrap the batch in a JSON array.
  const records = messages.map(m => (typeof m === "string" ? JSON.parse(m) : m));
  const payload = JSON.stringify(records);

await new Promise((resolve, reject) => {
    const req = https.request(
      {
        hostname: KF_URL,
        port: 443,
        path: "/api/v2/logs",
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          "DD-API-KEY": KF_API_KEY,
          "Content-Length": Buffer.byteLength(payload),
        },
      },
      res => {
        let body = "";
        res.on("data", chunk => { body += chunk; });
        res.on("end", () => {
          context.log(`Kloudfuse response: ${res.statusCode}`);
          if (res.statusCode >= 200 && res.statusCode < 300) {
            resolve();
          } else {
            reject(new Error(`Kloudfuse ingester returned ${res.statusCode}: ${body}`));
          }
        });
      }
    );
    req.on("error", reject);
    req.write(payload);
    req.end();
  });
};

Deploy the function:

cd kloudfuse-azure-fn
func azure functionapp publish <function-app-name>

Step 3: Configure Diagnostic Settings

Diagnostic Settings control which Azure resources send logs to the Event Hub.

Retrieve the Authorization Rule Resource ID

Both activity log and resource log diagnostic settings require the full Azure Resource ID of the Event Hub authorization rule. Retrieve it with:

az eventhubs namespace authorization-rule show \
  --name kloudfuse-policy \
  --namespace-name kloudfuse-logs \
  --resource-group <resource-group> \
  --query id \
  --output tsv

Save the output as EVENT_HUB_AUTH_RULE_RESOURCE_ID. It follows the form: /subscriptions/<sub>/resourceGroups/<rg>/providers/Microsoft.EventHub/namespaces/kloudfuse-logs/authorizationRules/kloudfuse-policy

Activity Logs (Subscription-Level)

Activity logs cover all API operations performed within a subscription. Configure them once per subscription:

az monitor diagnostic-settings subscription create \
  --name kloudfuse-activity-logs \
  --event-hub-name kloudfuse \
  --event-hub-auth-rule "$EVENT_HUB_AUTH_RULE_RESOURCE_ID" \
  --logs '[\
    {"category": "Administrative", "enabled": true},\
    {"category": "Security",       "enabled": true},\
    {"category": "ServiceHealth",  "enabled": true},\
    {"category": "Alert",          "enabled": true},\
    {"category": "Policy",         "enabled": true}\
  ]'

Resource Logs (Per-Resource)

Resource logs must be enabled individually for each Azure resource you want to monitor. The following example enables diagnostic settings for an Azure SQL database:

az monitor diagnostic-settings create \
  --name kloudfuse \
  --resource <resource-id> \
  --event-hub-name kloudfuse \
  --event-hub-rule "$EVENT_HUB_AUTH_RULE_RESOURCE_ID" \
  --logs '[{"categoryGroup": "allLogs", "enabled": true}]' \
  --metrics '[{"category": "AllMetrics", "enabled": false}]'

Replace <resource-id> with the Azure Resource ID of the resource to monitor. Use --logs '[{"categoryGroup": "allLogs", "enabled": true}]' to capture all log categories.

Verify the Integration

Confirm the Function App is Processing Events

  1. In the Azure Portal, open the <function-app-name> Function App.
  2. Click Functions in the left menu and select the kloudfuse-log-forwarder function.
  3. Click Monitor to view recent invocations. Each row corresponds to one batch of Event Hub messages. The Status column must show Success.
  4. Click a recent invocation to view the log output. A line like Kloudfuse response: 200 confirms successful delivery.

Confirm Logs are Arriving in Kloudfuse

  1. In the Kloudfuse UI, click the Logs tab and select Search from the drop-down.
  2. Set the time picker to the last 15 minutes.
  3. In the search bar, click Advanced Search and enter the following FuseQL query to confirm Azure logs are flowing:
source="azure"

Any result confirms that Azure log records are reaching Kloudfuse. 4. To filter by log type, use the category field (set by Azure Diagnostic Settings):

category="Administrative"
  1. To find all Azure Active Directory sign-in events:
source="azure" and operationName="Sign-in activity"
  1. To count log volume by Azure resource type:
source="azure" | count by resourceType

Troubleshooting

Function App Has No Invocations

The Function App is not receiving events from the Event Hub.

  1. Confirm that Diagnostic Settings are configured and pointing to the correct Event Hub Namespace and hub name.
  2. In the Azure Portal, open the Event Hub and click Process data > Explore. Verify that incoming message counts are non-zero after making an API call in your subscription.
  3. Confirm the EventHubConnection application setting in the Function App contains the correct connection string, including the EntityPath=kloudfuse suffix.
  4. Check that the authorization rule has both Listen and Send rights.

Function Invocations Fail with HTTP 5xx

The Function App is delivering to Kloudfuse but receiving error responses.

  1. In the Function App Monitor view, click a failed invocation and check the log for the HTTP status code returned by Kloudfuse.
  2. 401 or 403 — the KF_API_KEY value is incorrect or expired. Regenerate the key in Kloudfuse under Administration > API Keys and update the app setting.
  3. 404 — the KF_URL is incorrect or includes an https:// prefix. The setting must be the hostname only (for example kloudfuse.example.com). Verify the hostname is correct and that the Kloudfuse ingestion endpoint (/api/v2/logs) is reachable from the Function App.
  4. 5xx — the Kloudfuse ingester returned an error. Check the Kloudfuse pod logs: kubectl logs -n kfuse -l app=ingester.

Logs Appear in the Function App but Not in Kloudfuse

  1. Confirm the KF_URL application setting contains the hostname only (for example kloudfuse.example.com) with no https:// prefix and no trailing slash.
  2. Confirm that the Function App can reach the Kloudfuse endpoint. If the Function App runs inside a VNet with restricted egress, add an outbound rule allowing HTTPS to the Kloudfuse IP range.
  3. Check whether the log payload is valid JSON. The function forwards raw Event Hub messages; if Azure emits malformed records, the ingester may reject them silently.

Event Hub Lag is Growing

The Function App is falling behind the Event Hub.

  1. In the Azure Portal, open the Event Hub and view the Consumer Groups lag metric for the Function App consumer group.
  2. If lag is consistently above zero, increase the Event Hub partition count: az eventhubs eventhub update --partition-count 8 …​
  3. Alternatively, increase the Function App plan to a Premium or Dedicated plan to allow more concurrent executions.

External References