├── README.md ├── docker-compose.yml ├── grafana └── datasource.yml ├── openswoole └── server.php └── prometheus └── prometheus.yml /README.md: -------------------------------------------------------------------------------- 1 | # Open Swoole Dashboard 2 | 3 | [![Latest Stable Version](https://img.shields.io/packagist/v/openswoole/ide-helper.svg)](https://packagist.org/packages/openswoole/ide-helper) 4 | [![License](https://poser.pugx.org/openswoole/ide-helper/license)](LICENSE) 5 | [![GitHub stars](https://img.shields.io/github/stars/openswoole/swoole-src)](https://github.com/openswoole/swoole-src/stargazers) 6 | [![Twitter](https://img.shields.io/twitter/url/https/twitter.com/openswoole.svg?style=social&label=Follow%20%40OpenSwoole)](https://twitter.com/openswoole) 7 | 8 | This is the example repo of using Open Swoole Metrics in `v4.9.0` to bootstrap an [Open Swoole Dashboard](https://openswoole.com/dashboard) with [Metrics in Open Swoole](https://openswoole.com/docs/modules/swoole-server-stats), [Grafana](https://grafana.com/) and [Prometheus](https://prometheus.io/). 9 | 10 | Docker and Docker Compose are requried. 11 | 12 | ### Bootstrap Open Swoole Dashboard 13 | 14 | Make sure openswoole version >= 4.9.0: 15 | 16 | ```bash 17 | docker pull openswoole/swoole:latest 18 | docker run --rm openswoole/swoole:latest php --ri openswoole 19 | ``` 20 | 21 | Start the demo server and dashboard: 22 | 23 | ```bash 24 | git clone git@github.com:openswoole/dashboard.git 25 | cd dashboard 26 | docker-compose up 27 | ``` 28 | 29 | ### Open Swoole Metrics 30 | 31 | Find /metrics output at `http://127.0.0.1:9501/metrics` 32 | 33 | ### Prometheus UI 34 | 35 | Find Prometheus server at `http://127.0.0.1:9090/` 36 | 37 | Open Swoole Metrics 38 | 39 | ### Grafana Dashboard 40 | 41 | 1. Find `http://127.0.0.1:3000/login`, the default username and password are `openswoole:openswoole`. 42 | 2. Import Open Swoole Dashboard at `http://127.0.0.1:3000/dashboard/import`, enter ID `15418` and hit load button. 43 | 3. Send some traffic with wrk using `wrk -t4 -c16 -d5 --latency http://127.0.0.1:9501/` 44 | 4. Have fun with OpenSwoole Dashboard 45 | 46 | Open Swoole Dashboard 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | services: 2 | openswoole: 3 | image: openswoole/swoole:latest 4 | container_name: openswoole 5 | ports: 6 | - 9501:9501 7 | volumes: 8 | - ./openswoole:/var/www 9 | prometheus: 10 | image: prom/prometheus 11 | container_name: prometheus 12 | command: 13 | - '--config.file=/etc/prometheus/prometheus.yml' 14 | ports: 15 | - 9090:9090 16 | restart: unless-stopped 17 | volumes: 18 | - ./prometheus:/etc/prometheus 19 | - prom_data:/prometheus 20 | grafana: 21 | image: grafana/grafana 22 | container_name: grafana 23 | ports: 24 | - 3000:3000 25 | restart: unless-stopped 26 | environment: 27 | - GF_SECURITY_ADMIN_USER=openswoole 28 | - GF_SECURITY_ADMIN_PASSWORD=openswoole 29 | volumes: 30 | - ./grafana:/etc/grafana/provisioning/datasources 31 | volumes: 32 | prom_data: -------------------------------------------------------------------------------- /grafana/datasource.yml: -------------------------------------------------------------------------------- 1 | apiVersion: 1 2 | 3 | datasources: 4 | - name: Prometheus 5 | type: prometheus 6 | url: http://prometheus:9090 7 | isDefault: true 8 | access: proxy 9 | editable: true -------------------------------------------------------------------------------- /openswoole/server.php: -------------------------------------------------------------------------------- 1 | column('name', Swoole\Table::TYPE_STRING, 64); 9 | $table->column('id', Swoole\Table::TYPE_INT, 4); //1,2,4,8 10 | $table->column('num', Swoole\Table::TYPE_FLOAT); 11 | $table->create(); 12 | 13 | $table1 = new Swoole\Table(1024); 14 | $table1->column('name', Swoole\Table::TYPE_STRING, 64); 15 | $table1->column('id', Swoole\Table::TYPE_INT, 4); //1,2,4,8 16 | $table1->column('num', Swoole\Table::TYPE_FLOAT); 17 | $table1->create(); 18 | 19 | $server = new Swoole\HTTP\Server("0.0.0.0", 9501); 20 | $server->set([ 21 | 'worker_num' => 4, 22 | 'task_worker_num' => 10, 23 | //'max_request' => 10000, 24 | //'max_request_grace' => 0, 25 | ]); 26 | 27 | $process = new Swoole\Process(function($process) use ($server) 28 | { 29 | while(true) 30 | { 31 | $msg = $process->read(); 32 | 33 | foreach($server->connections as $conn) 34 | { 35 | $server->send($conn, $msg); 36 | } 37 | } 38 | }); 39 | 40 | $server->addProcess($process); 41 | 42 | $server->on("Start", function(Server $server) 43 | { 44 | echo "Open Swoole server is started at http://0.0.0.0:9501\n"; 45 | }); 46 | 47 | class A { 48 | public string $a = ''; 49 | 50 | function __construct() { 51 | $this->a = str_repeat('abcd', 1000); 52 | } 53 | }; 54 | 55 | $server->on("Request", function(Request $request, Response $response) use ($server) 56 | { 57 | // memory leak example 58 | // global $c; 59 | // $c[] = new A(); 60 | // Notice: add ACL rules and don't expose the metrics to the internet 61 | $response->header("Content-Type", "text/plain"); 62 | return $response->end($server->stats(\OPENSWOOLE_STATS_OPENMETRICS)); 63 | 64 | }); 65 | 66 | $server->on('Task', function (Swoole\Server $server, $task_id, $reactorId, $data) 67 | { 68 | echo "Task Worker Process received data"; 69 | echo "#{$server->worker_id}\tonTask: [PID={$server->worker_pid}]: task_id=$task_id, data_len=" . strlen($data) . "." . PHP_EOL; 70 | $server->finish($data); 71 | }); 72 | 73 | $server->start(); -------------------------------------------------------------------------------- /prometheus/prometheus.yml: -------------------------------------------------------------------------------- 1 | global: 2 | scrape_interval: 15s 3 | scrape_timeout: 10s 4 | evaluation_interval: 15s 5 | alerting: 6 | alertmanagers: 7 | - static_configs: 8 | - targets: [] 9 | scheme: http 10 | timeout: 10s 11 | api_version: v1 12 | scrape_configs: 13 | - job_name: prometheus 14 | honor_timestamps: true 15 | scrape_interval: 15s 16 | scrape_timeout: 10s 17 | metrics_path: /metrics 18 | scheme: http 19 | static_configs: 20 | - targets: 21 | - localhost:9090 22 | - job_name: openswoole 23 | honor_timestamps: true 24 | scrape_interval: 15s 25 | scrape_timeout: 10s 26 | metrics_path: /metrics 27 | scheme: http 28 | static_configs: 29 | - targets: 30 | - openswoole:9501 --------------------------------------------------------------------------------