I. Lời mở đầu
Các dữ liệu thống kê là một phần không thể thiếu của các dự án, đặc biệt là các dự án product hay startup. Các con số này luôn song song đồng hành cùng sản phẩm từ lúc bắt đầu đến khi ra mắt và phát triển. Và đương nhiên rồi việc thu thập kết quả các key metrics hằng ngày là điều vô cùng cần thiết. Ví dụ đơn giản như này, Viblo là sản phẩm product của mình. Các dữ liệu hằng ngày mà mình cần ở Viblo tính đến đến thời điểm báo cáo có thể là:
- Tổng số users
- Tổng số users mới
- Tổng số active users trong ngày, trong tuần, trong tháng
- Tổng số bài viết
- Tổng số bài viết mới
- ….
Và các con số này sẽ được lưu lại theo ngày, từ đó mình sẽ thấy được sự tăng trưởng và biến động theo từng ngày nữa. Từ những thông số đó mình sẽ biết được hệ thống đã, đang đạt được những thành quả tích cực nào hay cần cải thiện và phát triển những gì.
II. Nội dung chính
Chúng ta không thể phủ nhận rằng việc thu thập data system statistics là cực kỳ thiết yếu, chính vì vậy hãy làm việc này để giúp sản phẩm, hệ thống của bạn được tốt hơn.
Nhận thấy điều này là hữu ích nên mình có dành một chút thời gian và có viết ra một package tạm đặt tên là: laravel system statistics
Giới thiệu về package laravel system statistics
Mình xây dựng package vanquynguyen/laravel-system-statistics
giúp chúng ta có thể dễ dàng thu thập các dữ liệu hệ thống theo các key metrics của riêng mình. Tất cả dữ liệu sẽ được lưu trong bảng system_statistics
để tiện cho việc sử dụng sau này.
Download tại: Laravel System statistics package
Cài đặt package
Bạn có thể cài đặt package thông qua composer:
1 2 | composer <span class="token keyword">require</span> vanquynguyen<span class="token operator">/</span>laravel<span class="token operator">-</span>system<span class="token operator">-</span>statistics |
Sau khi cài đặt xong bạn cần chạy command để tạo migrations tự động:
1 2 | php artisan vendor<span class="token punctuation">:</span>publish <span class="token operator">--</span>provider<span class="token operator">=</span><span class="token double-quoted-string string">"VanquySystemStatisticsSystemStatisticServiceProvider"</span> <span class="token operator">--</span>tag<span class="token operator">=</span><span class="token double-quoted-string string">"migrations"</span> |
Và đương nhiên rồi sau khi migrations file đã được tạo bạn cần phải chạy migrate
để thêm bảng vào database
1 2 | php artisan migrate |
Đừng quên chạy lệnh để tạo file config nữa
1 2 | php artisan vendor<span class="token punctuation">:</span>publish <span class="token operator">--</span>provider<span class="token operator">=</span><span class="token double-quoted-string string">"VanquySystemStatisticsSystemStatisticServiceProvider"</span> <span class="token operator">--</span>tag<span class="token operator">=</span><span class="token double-quoted-string string">"config"</span> |
Package có viết sẵn cho bạn một command để thu thập dữ liệu, có sẵn rồi thì ngần ngại gì mà không dùng nhỉ =))
1 2 | php artisan vendor<span class="token punctuation">:</span>publish <span class="token operator">--</span>provider<span class="token operator">=</span><span class="token double-quoted-string string">"VanquySystemStatisticsSystemStatisticServiceProvider"</span> <span class="token operator">--</span>tag<span class="token operator">=</span><span class="token double-quoted-string string">"commands"</span> |
Hướng dẫn sử dụng
- Models
Bạn có thể sử dụng model theo namespace
VanquySystemStatisticsModelsSystemStatistic
.
1 2 3 4 | <span class="token keyword">use</span> <span class="token package">VanquySystemStatisticsModelsSystemStatistic</span><span class="token punctuation">;</span> SystemStatistic<span class="token punctuation">:</span><span class="token punctuation">:</span><span class="token function">all</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> |
Hoặc nếu bạn muốn tạo trong AppModels để dễ dàng mở rộng thì có thể tạo và extends Model đã được tạo sẵn trong package
1 2 3 4 5 6 7 8 9 10 | <span class="token keyword">namespace</span> <span class="token package">AppModels</span><span class="token punctuation">;</span> <span class="token keyword">use</span> <span class="token package">VanquySystemStatisticsModelsSystemStatistic</span><span class="token punctuation">;</span> <span class="token keyword">class</span> <span class="token class-name">StatisticModel</span> <span class="token keyword">extends</span> <span class="token class-name">SystemStatistic</span> <span class="token punctuation">{</span> <span class="token comment">//</span> <span class="token punctuation">}</span> |
- Có thể sử dụng một số hàm sẵn có:
Hiện tại package có viết sẵn 2 class: Collector
và Repository
. Class Collector
là những đoạn code giúp ta thu thập dữ liệu cho các key metrics, Repository
cung cấp một số hàm lấy data theo điều kiện. Với namespace là:
VanquySystemStatisticsComponentsCollector
và VanquySystemStatisticsComponentsRepository
- Commands
Thu thập data theo ngày
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | <span class="token keyword">namespace</span> <span class="token package">AppConsoleCommands</span><span class="token punctuation">;</span> <span class="token keyword">use</span> <span class="token package">VanquySystemStatisticsComponentsCollector</span><span class="token punctuation">;</span> <span class="token comment">/** * Execute the console command. * * @return mixed */</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">handle</span><span class="token punctuation">(</span>Collector <span class="token variable">$statsCollector</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token variable">$dateArg</span> <span class="token operator">=</span> <span class="token variable">$this</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">option</span><span class="token punctuation">(</span><span class="token single-quoted-string string">'date'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token variable">$date</span> <span class="token operator">=</span> <span class="token variable">$dateArg</span> <span class="token operator">!==</span> <span class="token constant">null</span> <span class="token operator">?</span> Carbon<span class="token punctuation">:</span><span class="token punctuation">:</span><span class="token function">createFromFormat</span><span class="token punctuation">(</span><span class="token single-quoted-string string">'Y-m-d'</span><span class="token punctuation">,</span> <span class="token variable">$dateArg</span><span class="token punctuation">)</span> <span class="token punctuation">:</span> Carbon<span class="token punctuation">:</span><span class="token punctuation">:</span><span class="token function">now</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">subDay</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token variable">$this</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">deleteOldStatistics</span><span class="token punctuation">(</span><span class="token variable">$date</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token variable">$queries</span> <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token variable">$statistics</span> <span class="token operator">=</span> <span class="token variable">$statsCollector</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">forDate</span><span class="token punctuation">(</span><span class="token variable">$queries</span><span class="token punctuation">,</span> <span class="token variable">$date</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token variable">$data</span> <span class="token operator">=</span> <span class="token variable">$statistics</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">map</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token variable">$item</span><span class="token punctuation">,</span> <span class="token variable">$key</span><span class="token punctuation">)</span> <span class="token keyword">use</span> <span class="token punctuation">(</span><span class="token variable">$date</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">[</span> <span class="token single-quoted-string string">'type'</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token variable">$key</span><span class="token punctuation">,</span> <span class="token single-quoted-string string">'data'</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token variable">$item</span><span class="token punctuation">,</span> <span class="token single-quoted-string string">'date'</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token variable">$date</span><span class="token punctuation">,</span> <span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> SystemStatistic<span class="token punctuation">:</span><span class="token punctuation">:</span><span class="token function">insert</span><span class="token punctuation">(</span><span class="token variable">$data</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">toArray</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> |
Bạn cần thêm các query ứng với key metrics mà bạn cần và thêm vào biến $queries, Ví dụ:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <span class="token keyword">namespace</span> <span class="token package">AppConsoleCommands</span><span class="token punctuation">;</span> <span class="token keyword">use</span> <span class="token package">VanquySystemStatisticsComponentsCollector</span><span class="token punctuation">;</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">handle</span><span class="token punctuation">(</span>Collector <span class="token variable">$statsCollector</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token variable">$queries</span> <span class="token operator">=</span> <span class="token punctuation">[</span> <span class="token punctuation">[</span> <span class="token single-quoted-string string">'type'</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token single-quoted-string string">'total_users'</span><span class="token punctuation">,</span> <span class="token single-quoted-string string">'query'</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token variable">$statsCollector</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">countTotalSystem</span><span class="token punctuation">(</span><span class="token single-quoted-string string">'users'</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span> <span class="token punctuation">}</span> |
Send daily report
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | <span class="token keyword">namespace</span> <span class="token package">AppConsoleCommands</span><span class="token punctuation">;</span> <span class="token keyword">use</span> <span class="token package">VanquySystemStatisticsComponentsRepository</span> <span class="token comment">/** * Execute the console command. * * @return mixed */</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">handle</span><span class="token punctuation">(</span>Repository <span class="token variable">$statsRepository</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token variable">$currentDate</span> <span class="token operator">=</span> Carbon<span class="token punctuation">:</span><span class="token punctuation">:</span><span class="token function">now</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">subDay</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token variable">$lastDate</span> <span class="token operator">=</span> Carbon<span class="token punctuation">:</span><span class="token punctuation">:</span><span class="token function">now</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">subDay</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token variable">$types</span> <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token variable">$dataStatistics</span> <span class="token operator">=</span> <span class="token variable">$statsRepository</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">getStatisticsForReport</span><span class="token punctuation">(</span><span class="token variable">$types</span><span class="token punctuation">,</span> <span class="token variable">$currentDate</span><span class="token punctuation">,</span> <span class="token variable">$lastDate</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token variable">$dataStatistics</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> |
Bạn cần thêm các type vào biến $types để lấy ra dữ liệu của các type mà bạn cần, ví dụ:
1 2 3 | <span class="token variable">$type</span> <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token single-quoted-string string">'total_users'</span><span class="token punctuation">,</span> <span class="token single-quoted-string string">'total_new_users'</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span> |
III. Tạm kết
Hy vọng package thực sự hữu ích cho mọi người. Rất mong được sự góp ý, và contribute Laravel System statistics package.