Operations 6 min read

How to Integrate Zipkin Distributed Tracing with Webman and Alibaba Cloud ARMS

This guide explains Zipkin's architecture, data reporting methods, and step‑by‑step integration with the Webman framework, including middleware implementation, configuration, and visual monitoring on Alibaba Cloud ARMS, enabling developers to trace requests, monitor SQL, and diagnose performance issues in microservice environments.

Open Source Tech Hub
Open Source Tech Hub
Open Source Tech Hub
How to Integrate Zipkin Distributed Tracing with Webman and Alibaba Cloud ARMS

Zipkin Overview

Zipkin is an open‑source distributed tracing system that reconstructs call chains, aggregates request statistics, visualizes topology, and analyzes service dependencies, helping developers diagnose performance bottlenecks in microservice architectures.

Architecture

Clients instrument applications using language‑specific SDKs that implement the OpenTracing standard. Tracing data is sent to a Zipkin backend, which aggregates, stores, and provides real‑time views such as trace details, performance overviews, and service topology. The data can be exported to downstream services for offline analysis or alerting.

Data Reporting Options

Direct reporting from traditional PHP frameworks (e.g., ThinkPHP 6.0, Laravel, Yii 2.0) without an agent.

Agent‑based reporting for modern command‑line frameworks such as Webman.

Webman Quick‑Start

1. Enable Alibaba Cloud ARMS

Visit the ARMS console at https://arms.console.aliyun.com/ and enable the service (typically a 15‑day trial).

2. Obtain the reporting endpoint URL

In the Tracing console global settings (https://tracing.console.aliyun.com/#/globalSetting/cn-hangzhou/process) copy the data‑reporting endpoint. Use a public endpoint unless the server resides in an Alibaba Cloud VPC.

3. Install Zipkin SDK

composer require openzipkin/zipkin

4. Implement Middleware

Create app\middleware\ArmsMiddleware.php to initialize a Zipkin tracer, schedule periodic flushing, and record root spans, request information, and SQL queries.

<?php
declare(strict_types=1);
namespace app\middleware;

use Monolog\Handler\ErrorLogHandler;
use Monolog\Logger;
use think\facade\Db;
use Webman\MiddlewareInterface;
use Webman\Http\Response;
use Webman\Http\Request;
use Zipkin\Reporters\Http as HttpReporter;
use Zipkin\TracingBuilder;
use Zipkin\Samplers\BinarySampler;
use Zipkin\Endpoint;
use Workerman\Timer;
use const Zipkin\Tags\SQL_QUERY;

class ArmsMiddleware implements MiddlewareInterface {
    public function process(Request $request, callable $next): Response {
        static $tracing = null, $tracer = null;
        if (!$tracing) {
            $endpoint = Endpoint::create('OpenTechStack', $request->getRealIp(), null, 2555);
            $logger = new Logger('log');
            $logger->pushHandler(new ErrorLogHandler());
            $reporter = new HttpReporter(['endpoint_url' => config('security')['endpoint_url']]);
            $sampler = BinarySampler::createAsAlwaysSample();
            $tracing = TracingBuilder::create()
                ->havingLocalEndpoint($endpoint)
                ->havingSampler($sampler)
                ->havingReporter($reporter)
                ->build();
            $tracer = $tracing->getTracer();
            Timer::add(55, fn() => $tracer->flush());
            register_shutdown_function(fn() => $tracer->flush());
        }
        $rootSpan = $tracer->newTrace();
        $rootSpan->setName($request->controller . "::" . $request->action);
        $rootSpan->start();
        $request->rootSpan = $rootSpan;
        $request->tracer = $tracer;
        $result = $next($request);
        if (class_exists(Db::class)) {
            $logs = Db::getDbLog(true);
            if (!empty($logs['sql'])) {
                foreach ($logs['sql'] as $sql) {
                    $sqlSpan = $tracer->newChild($rootSpan->getContext());
                    $sqlSpan->setName(SQL_QUERY);
                    $sqlSpan->start();
                    $sqlSpan->tag('db.statement', $sql);
                    $sqlSpan->finish();
                }
            }
        }
        $rootSpan->finish();
        return $result;
    }
}

5. Register Middleware Globally

return [
    '' => [
        \app\middleware\ArmsMiddleware::class,
    ],
    // ... other middleware
];

6. View Tracing Results

Open the Alibaba Cloud Tracing console at https://tracing.console.aliyun.com/ to view interface and database monitoring dashboards.

MiddlewarePHPzipkinWebmanAlibabaCloudARMSDistributedTracing
Open Source Tech Hub
Written by

Open Source Tech Hub

Sharing cutting-edge internet technologies and practical AI resources.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.