Edit

Quickstart: Process real-time events by using Azure Functions

In this article, you use the Azure Developer CLI (azd) to create an Event Hubs trigger function for real-time event processing in Azure Functions. After verifying the code locally, you deploy it to a new serverless function app running in a Flex Consumption plan in Azure.

The project source uses azd to create the function app and related resources and to deploy your code to Azure. This deployment follows current best practices for secure and scalable Azure Functions deployments.

By default, the Flex Consumption plan follows a pay-for-what-you-use billing model, which means you can complete this article and only incur a small cost of a few USD cents or less in your Azure account.

This article supports version 4 of the Node.js programming model for Azure Functions.

This article supports version 2 of the Python programming model for Azure Functions.

Prerequisites

Initialize the project

Use the azd init command to create a local Azure Functions code project from a template.

In your local terminal or command prompt, run this azd init command in an empty folder:

azd init --template functions-quickstart-dotnet-azd-eventhub -e eventhub-dotnet

This command pulls the project files from the template repository and initializes the project in the current folder. The -e flag sets a name for the current environment. In azd, the environment maintains a unique deployment context for your app, and you can define more than one. The environment name is also used in the name of the resource group you create in Azure.

In your local terminal or command prompt, run this azd init command in an empty folder:

azd init --template functions-quickstart-typescript-azd-eventhub -e eventhub-ts

This command pulls the project files from the template repository and initializes the project in the current folder. The -e flag sets a name for the current environment. In azd, the environment maintains a unique deployment context for your app, and you can define more than one. The environment name is also used in the name of the resource group you create in Azure.

In your local terminal or command prompt, run this azd init command in an empty folder:

azd init --template functions-quickstart-python-azd-eventhub -e eventhub-py

This command pulls the project files from the template repository and initializes the project in the current folder. The -e flag sets a name for the current environment. In azd, the environment maintains a unique deployment context for your app, and you can define more than one. The environment name is also used in the name of the resource group you create in Azure.

Create and activate a virtual environment

In the root folder, run these commands to create and activate a virtual environment named .venv:

python3 -m venv .venv
source .venv/bin/activate

If Python doesn't install the venv package on your Linux distribution, run the following command:

sudo apt-get install python3-venv

In your local terminal or command prompt, run this azd init command in an empty folder:

azd init --template functions-quickstart-java-azd-eventhub -e eventhub-java

This command pulls the project files from the template repository and initializes the project in the current folder. The -e flag sets a name for the current environment. In azd, the environment maintains a unique deployment context for your app, and you can define more than one. The environment name is also used in the name of the resource group you create in Azure.

In your local terminal or command prompt, run this azd init command in an empty folder:

azd init --template functions-quickstart-javascript-azd-eventhub -e eventhub-js

This command pulls the project files from the template repository and initializes the project in the current folder. The -e flag sets a name for the current environment. In azd, the environment maintains a unique deployment context for your app, and you can define more than one. The environment name is also used in the name of the resource group you create in Azure.

In your local terminal or command prompt, run this azd init command in an empty folder:

azd init --template functions-quickstart-powershell-azd-eventhub -e eventhub-ps

This command pulls the project files from the template repository and initializes the project in the current folder. The -e flag sets a name for the current environment. In azd, the environment maintains a unique deployment context for your app, and you can define more than one. The environment name is also used in the name of the resource group you create in Azure.

Create Azure resources

Before you can run your function locally, you need to create an Event Hubs namespace and hub in Azure. Use azd provision to create these resources and configure your local settings by adding the required local.settings.json file.

  1. Run the following command to sign in to Azure:

    azd auth login
    

    Follow the prompts to authenticate by using your Azure account.

  2. From the root folder, run the following command to create your Azure resources:

    azd provision
    
  3. When prompted, provide these required deployment parameters:

    Parameter Description
    Azure subscription Subscription in which you create your resources.
    Azure location Azure region in which to create the resource group that contains the new Azure resources. Only regions that currently support the Flex Consumption plan are shown.
    vnetEnabled Use a value of False to avoid the extra overhead of creating virtual network resources.

    The azd provision command creates the required Azure resources, including an Event Hubs namespace and hub, a Flex Consumption function app, Application Insights, and a storage account. It also configures your local.settings.json file with the Event Hubs connection information.

Run in your local environment

  1. In a separate terminal window, start the Azurite storage emulator:

    azurite
    

    The local Functions host process uses the Azurite emulator for the internal storage connection (AzureWebJobsStorage) required by the runtime.

  1. To start the function app, run these commands in a terminal or command prompt to navigate to the src project folder and start the function app:

    cd src
    func start
    
  1. To start the function app, run this command in a terminal or command prompt:

    func start
    
  1. To build and start the function app, run these commands in a terminal or command prompt:

    mvn clean package
    mvn azure-functions:run
    
  1. To install dependencies and start the function app, run these commands in a terminal or command prompt:

    npm install
    npm start  
    
  1. To install dependencies and start the function app, run these commands in a terminal or command prompt:

    cd src
    npm install
    npm start  
    
  1. To start the function app, run this command in a terminal or command prompt:

    func start
    
  1. If prompted, allow Core Tools (func.exe) to be called through the firewall.

  2. When the Functions host starts in your local project folder, it writes information about your functions to the terminal output.

    This sample includes a Timer trigger function that automatically generates news articles every 10 seconds and sends them to Event Hubs. The Event Hubs trigger function then processes these events and performs sentiment analysis and engagement tracking.

    You see output similar to this example:

     [2026-03-02T22:37:30.151Z] Executing 'Functions.EventHubsTrigger'
     [2026-03-02T22:37:30.159Z] Trigger Details: PartitionId: 24, OffsetString: 0, EnqueueTimeUtc: 2026-03-02T22:37:29.1790000+00:00, SequenceNumber: 0, Count: 1, Offset: 0, PartionId: 24
     [2026-03-02T22:37:30.169Z] ⭐ High-engagement article NEWS-20260302-0580CB82 (Views: 6123, Sentiment: 0.57) featured!
     [2026-03-02T22:37:30.174Z] 🔥 Viral article: NEWS-20260302-0580CB82 - 6,123 views
     [2026-03-02T22:37:30.181Z] 🌟 Featured article: NEWS-20260302-0580CB82
     [2026-03-02T22:37:30.185Z] ✅ Successfully processed article NEWS-20260302-0580CB82 - 'Technology Breakthrough in Renewable Energy Technology' by Sarah Johnson
     [2026-03-02T22:37:30.191Z] 📰 Processed 1 news articles, 0 failed in batch of 1
     [2026-03-02T22:37:30.196Z] 📊 NEWS BATCH SUMMARY: 1 articles | Total Views: 6,123 | Avg Views: 6,123 | Avg Sentiment: 0.57 | Status: [Featured: 1]
     [2026-03-02T22:37:30.200Z] 📂 Top Categories: [Health: 1] | Top Sources: [Innovation Weekly: 1]
     [2026-03-02T22:37:30.204Z] 🔥 Viral articles in batch: 1
     [2026-03-02T22:37:30.207Z] Executed 'Functions.EventHubsTrigger' (Succeeded, Duration=55ms)
     
  3. When you're done, press Ctrl+C in the terminal window to stop the func.exe host process.

  4. Close the window in which Azurite is running.

  1. Run deactivate to shut down the virtual environment.

Review the code (optional)

You can review the code that defines the Event Hubs trigger function:

using System.Text.Json;
using Azure.Messaging.EventHubs;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.Logging;

namespace function_app;

public class EventHubsTrigger
{
    private readonly ILogger<EventHubsTrigger> _logger;
    private readonly NewsProcessingService _newsService;

    public EventHubsTrigger(ILogger<EventHubsTrigger> logger, NewsProcessingService newsService)
    {
        _logger = logger;
        _newsService = newsService;
    }

    [Function(nameof(EventHubsTrigger))]
    public async Task Run([EventHubTrigger("news", Connection = "EventHubConnection")] EventData[] input)
    {
        var processedArticles = new List<NewsArticle>();
        var failedEvents = 0;
        
        foreach (var message in input)
        {
            try
            {
                var messageBody = message.EventBody.ToString();

                // Parse the news article event
                var article = ParseNewsArticleEvent(messageBody);

                if (article != null)
                {
                    processedArticles.Add(article);
                }
                else
                {
                    failedEvents++;
                }
            }
            catch (Exception ex)
            {
                failedEvents++;
                _logger.LogWarning($"Error processing message: {ex.Message}");
            }
        }

        // Log summary of this execution
        _logger.LogInformation($"📰 Processed {processedArticles.Count} news articles, {failedEvents} failed in batch of {input.Length}");

You can review the complete template project here.

package com.function;

import com.microsoft.azure.functions.*;
import com.microsoft.azure.functions.annotation.*;

import java.time.Instant;
import java.util.*;
import java.util.logging.Logger;

/**
 * Azure Function that processes messages from an input Event Hub,
 * adds metadata, and sends processed messages to an output Event Hub.
 */
public class EventHubsTriggerFunction {

    @FunctionName("EventHubsTrigger")
    public void run(
            @EventHubTrigger(
                name = "messages",
                eventHubName = "%INPUT_EVENTHUB_NAME%",
                connection = "EventHubConnection",
                cardinality = Cardinality.MANY)
            List<String> messages,
            @EventHubOutput(
                name = "output",
                eventHubName = "%OUTPUT_EVENTHUB_NAME%",
                connection = "EventHubConnection")
            OutputBinding<List<String>> output,
            final ExecutionContext context) {

        Logger logger = context.getLogger();
        logger.info(String.format("🔄 Event hub function processing %d message(s)", messages.size()));

        List<String> processedMessages = new ArrayList<>();

        for (String message : messages) {
            try {
                logger.info("📨 Processing event: " + message);

                // Create processed message with additional metadata
                String processedMessage = String.format(
                    "{\"id\":\"%s\",\"message\":%s,\"timestamp\":\"%s\"}",
                    UUID.randomUUID().toString(),
                    message,
                    Instant.now().toString());

                processedMessages.add(processedMessage);
                logger.info("\u2728 Message processed: " + processedMessage);

            } catch (Exception e) {
                logger.severe("\u274C Error processing message: " + e.getMessage());
            }
        }

        // Send processed messages to output Event Hub
        if (!processedMessages.isEmpty()) {
            output.setValue(processedMessages);
            logger.info(String.format("📤 Sent %d message(s) to output Event Hub", processedMessages.size()));
        }
    }
}

You can review the complete template project here.

const { app, output } = require("@azure/functions");

const eventHubOutput = output.eventHub({
    connection: 'EventHubConnection',
    eventHubName: '%OUTPUT_EVENTHUB_NAME%'
});

async function EventHubsTrigger(messages, context) {
    context.log(`🔄 Event hub function processing ${messages.length} message(s)`);
    
    const processedMessages = [];
    
    for (const message of messages) {
        try {
            // Parse the incoming message
            const eventData = typeof message === 'string' ? JSON.parse(message) : message;
            context.log('📨 Processing event:', eventData);
            
            // Create processed message with additional metadata
            const processedMessage = {
                id: eventData.id || crypto.randomUUID(),
                message: eventData.message || JSON.stringify(eventData),
                timestamp: new Date().toISOString()
            };
            
            processedMessages.push(processedMessage);
            context.log('✨ Message processed:', processedMessage);
            
        } catch (error) {
            context.error(`❌ Error processing message: ${error}`);
        }
    }
    
    // Send processed messages to output Event Hub
    if (processedMessages.length > 0) {
        context.extraOutputs.set(eventHubOutput, processedMessages);
        context.log(`📤 Sent ${processedMessages.length} message(s) to output Event Hub`);
    }
}

app.eventHub('EventHubsTrigger', {
    connection: 'EventHubConnection',
    eventHubName: '%INPUT_EVENTHUB_NAME%',
    cardinality: 'many',
    extraOutputs: [eventHubOutput],
    handler: EventHubsTrigger
});

You can review the complete template project here.

import { app, InvocationContext, output } from "@azure/functions";

interface EventMessage {
    id: string;
    message: string;
    timestamp: string;
}

const eventHubOutput = output.eventHub({
    connection: 'EventHubConnection',
    eventHubName: '%OUTPUT_EVENTHUB_NAME%'
});

export async function EventHubsTrigger(messages: unknown[], context: InvocationContext): Promise<void> {
    context.log(`🔄 Event hub function processing ${messages.length} message(s)`);
    
    const processedMessages: EventMessage[] = [];
    
    for (const message of messages) {
        try {
            // Parse the incoming message
            const eventData = typeof message === 'string' ? JSON.parse(message) : message;
            context.log('📨 Processing event:', eventData);
            
            // Create processed message with additional metadata
            const processedMessage: EventMessage = {
                id: eventData.id || crypto.randomUUID(),
                message: eventData.message || JSON.stringify(eventData),
                timestamp: new Date().toISOString()
            };
            
            processedMessages.push(processedMessage);
            context.log('✨ Message processed:', processedMessage);
            
        } catch (error) {
            context.error(`❌ Error processing message: ${error}`);
        }
    }
    
    // Send processed messages to output Event Hub
    if (processedMessages.length > 0) {
        context.extraOutputs.set(eventHubOutput, processedMessages);
        context.log(`📤 Sent ${processedMessages.length} message(s) to output Event Hub`);
    }
}

app.eventHub('EventHubsTrigger', {
    connection: 'EventHubConnection',
    eventHubName: '%INPUT_EVENTHUB_NAME%',
    cardinality: 'many',
    extraOutputs: [eventHubOutput],
    handler: EventHubsTrigger
});

You can review the complete template project here.

param($InputEvents, $TriggerMetadata)

Write-Host "🔄 Event hub function processing $($InputEvents.Count) message(s)"

$processedMessages = @()

foreach ($message in $InputEvents) {
    try {
        # Parse the incoming message
        $eventData = $message | ConvertFrom-Json -ErrorAction SilentlyContinue
        if (-not $eventData) {
            $eventData = @{ message = $message }
        }

        Write-Host "📨 Processing event: $($eventData | ConvertTo-Json -Compress)"

        # Create processed message with additional metadata
        $processedMessage = @{
            id        = if ($eventData.id) { $eventData.id } else { [guid]::NewGuid().ToString() }
            message   = if ($eventData.message) { $eventData.message } else { ($eventData | ConvertTo-Json -Compress) }
            timestamp = (Get-Date).ToUniversalTime().ToString('o')
        }

        $processedMessages += $processedMessage
        Write-Host "✨ Message processed: $($processedMessage | ConvertTo-Json -Compress)"
    }
    catch {
        Write-Error "❌ Error processing message: $_"
    }
}

# Send processed messages to output Event Hub
if ($processedMessages.Count -gt 0) {
    Push-OutputBinding -Name OutputEvents -Value ($processedMessages | ConvertTo-Json -Compress)
    Write-Host "📤 Sent $($processedMessages.Count) message(s) to output Event Hub"
}

The trigger is defined in the corresponding function.json.

You can review the complete template project here.

import azure.functions as func
import logging
import json
from datetime import datetime, timezone
import random
import uuid
from typing import List

app = func.FunctionApp()

# News article data model
class NewsArticle:
            title=random.choice(titles_templates).format(topic=topic),
            content=f"Comprehensive coverage of the latest developments in {topic}. " * random.randint(10, 20),
            author=random.choice(authors),
            source=random.choice(sources),
            category=random.choice(categories),
            published_date=datetime.now(timezone.utc),
            view_count=random.randint(100, 10000),
            sentiment_score=round(random.uniform(-1.0, 1.0), 2),
            status=random.choice(["Published", "Featured"]),
            tags=[random.choice(topics) for _ in range(random.randint(3, 5))]
        )
        articles.append(article)
    
    # Send articles to Event Hub
    events_json = json.dumps([article.to_dict() for article in articles])
    event.set(events_json)
    
    logging.info(f'✅ HIGH-THROUGHPUT: Successfully generated {num_articles} news articles in ~10 seconds')


# Event Hub trigger - processes news articles
@app.event_hub_message_trigger(arg_name="events", event_hub_name="news",
                                connection="EventHubConnection")
def EventHubsTrigger(events: List[func.EventHubEvent]):
    """Process news articles from Event Hub with sentiment analysis and engagement tracking"""
    
    # Handle both single event and list of events
    if not isinstance(events, list):
        events = [events]
    
    batch_articles = []
    failed_count = 0
    
    for event in events:
        try:
            # Parse the event data
            event_data = json.loads(event.get_body().decode('utf-8'))
            
            # Handle both single article and array of articles
            articles = event_data if isinstance(event_data, list) else [event_data]
            
            for article_data in articles:
                # Process each article
                article_id = article_data.get('ArticleId')
                title = article_data.get('Title')
                author = article_data.get('Author')

You can review the complete template project here.

After you verify your function locally, it's time to publish it to Azure.

Deploy to Azure

This project is configured to use the azd up command to deploy your code to a new function app in a Flex Consumption plan in Azure. Since you already provisioned resources, this command deploys your code to the existing function app.

Tip

This project includes a set of Bicep files that azd uses to create a secure deployment to a Flex Consumption plan that follows best practices.

From the repository root folder, run the following command to deploy your code project to the function app in Azure:

azd deploy

The deployment packages your code and deploys it to the function app. When the command finishes, you see links to the resources you created.

Verify deployment

After deployment finishes, your Event Hubs trigger function automatically starts processing events as they arrive in the event hub.

  1. In the Azure portal, go to your new function app.

  2. Select Log stream from the left menu to monitor your function executions in real-time.

  3. You see log entries that show your Event Hubs trigger function processing events generated by the Timer trigger.

Redeploy your code

Run the azd up command as many times as you need to both provision your Azure resources and deploy code updates to your function app.

Note

Deployed code files are always overwritten by the latest deployment package.

Your initial responses to azd prompts and any environment variables generated by azd are stored locally in your named environment. Use the azd env get-values command to review all of the variables in your environment that were used when creating Azure resources.

Clean up resources

When you're done working with your function app and related resources, use this command to delete the function app and its related resources from Azure and avoid incurring any further costs:

azd down --no-prompt

Note

The --no-prompt option instructs azd to delete your resource group without a confirmation from you.

This command doesn't affect your local code project.