@@ -27,8 +27,10 @@ Track page views, API calls, user signups, or any other countable events.
2727 - [ Using the Redis Driver] ( #using-the-redis-driver )
2828- [ Usage] ( #usage )
2929 - [ Recording Metrics] ( #recording-metrics )
30+ - [ Recording with Values] ( #recording-with-values )
3031 - [ Recording with Categories] ( #recording-with-categories )
3132 - [ Recording with Dates] ( #recording-with-dates )
33+ - [ Recording Hourly Metrics] ( #recording-hourly-metrics )
3234 - [ Recording for Models] ( #recording-for-models )
3335 - [ Recording with Custom Attributes] ( #recording-with-custom-attributes )
3436 - [ Capturing & Committing] ( #capturing--committing )
@@ -148,7 +150,7 @@ Which ever method you use, metrics are recorded in the same way. Use whichever y
148150
149151For the rest of the documentation, we will use the ` metric ` helper for consistency and brevity.
150152
151- ### Metric Values
153+ ### Recording with Values
152154
153155By default, metrics have a value of ` 1 ` . You may specify a custom value in the ` record ` method:
154156
@@ -207,6 +209,61 @@ metric('jobs:completed')
207209 ->record(1250);
208210```
209211
212+ ### Recording Hourly Metrics
213+
214+ By default, metrics are recorded at the ** daily** level. For metrics that require hour-level granularity, you may use the ` hourly() ` method:
215+
216+ ``` php
217+ // Track API requests by hour
218+ metric('api:requests')
219+ ->hourly()
220+ ->record();
221+ ```
222+
223+ Hourly metrics include the hour (0-23) in addition to the year, month, and day, allowing you to track metrics at a more granular level:
224+
225+ ``` php
226+ use Carbon\Carbon;
227+
228+ // Record API requests for a specific hour
229+ metric('api:requests')
230+ ->date(Carbon::parse('2025-10-19 14:30:00'))
231+ ->hourly()
232+ ->record();
233+
234+ // This will be stored with hour = 14
235+ ```
236+
237+ Hourly metrics are stored separately from daily metrics, even for the same metric name:
238+
239+ ``` php
240+ metric('page:views')->record(); // Daily metric (hour = null)
241+ metric('page:views')->hourly()->record(); // Hourly metric (hour = current hour)
242+ ```
243+
244+ You can query hourly metrics using the ` thisHour() ` , ` lastHour() ` , and ` onDateTime() ` methods:
245+
246+ ``` php
247+ use DirectoryTree\Metrics\Metric;
248+
249+ // Get metrics for this hour
250+ $metrics = Metric::thisHour()->get();
251+
252+ // Get metrics for last hour
253+ $metrics = Metric::lastHour()->get();
254+
255+ // Get metrics for a specific date and hour
256+ $metrics = Metric::onDateTime(Carbon::parse('2025-10-19 14:00:00'))->get();
257+
258+ // Get API requests for the current hour
259+ $requests = Metric::thisHour()
260+ ->where('name', 'api:requests')
261+ ->sum('value');
262+ ```
263+
264+ > [ !tip]
265+ > Use hourly metrics sparingly, as they create 24x more database rows than daily metrics. Reserve hourly tracking for metrics that genuinely benefit from hour-level granularity.
266+
210267### Recording for Models
211268
212269Associate metrics with Eloquent models using the ` HasMetrics ` trait:
@@ -300,16 +357,16 @@ metric('api:requests')
300357Custom attributes are included in the metric's uniqueness check, meaning metrics with different attribute values are stored separately:
301358
302359``` php
303- metric('page_views ')->with(['source' => 'google'])->record(); // Creates metric #1
304- metric('page_views ')->with(['source' => 'facebook'])->record(); // Creates metric #2
305- metric('page_views ')->with(['source' => 'google'])->record(); // Increments metric #1
360+ metric('page:views ')->with(['source' => 'google'])->record(); // Creates metric #1
361+ metric('page:views ')->with(['source' => 'facebook'])->record(); // Creates metric #2
362+ metric('page:views ')->with(['source' => 'google'])->record(); // Increments metric #1
306363```
307364
308365This allows you to segment and analyze metrics by any dimension:
309366
310367``` php
311368// Get page views by source
312- $googleViews = Metric::where('name', 'page_views ')
369+ $googleViews = Metric::where('name', 'page:views ')
313370 ->where('source', 'google')
314371 ->sum('value');
315372
@@ -322,7 +379,7 @@ $conversions = Metric::thisMonth()
322379
323380// Get mobile vs desktop traffic
324381$mobileViews = Metric::today()
325- ->where('name', 'page_views ')
382+ ->where('name', 'page:views ')
326383 ->where('device', 'mobile')
327384 ->sum('value');
328385```
@@ -334,7 +391,7 @@ use DirectoryTree\Metrics\MetricData;
334391use DirectoryTree\Metrics\Facades\Metrics;
335392
336393Metrics::record(new MetricData(
337- name: 'page_views ',
394+ name: 'page:views ',
338395 additional: [
339396 'source' => 'google',
340397 'country' => 'US',
@@ -347,7 +404,7 @@ Or with the `PendingMetric` class:
347404``` php
348405use DirectoryTree\Metrics\PendingMetric;
349406
350- PendingMetric::make('page_views ')
407+ PendingMetric::make('page:views ')
351408 ->with(['source' => 'google', 'country' => 'US'])
352409 ->record();
353410```
0 commit comments