Skip to content

Commit 7b1f1de

Browse files
authored
Add table and job for daily tracking and recording of wiki metrics (#880)
* Add WikiDailyMetric table Add Job for the above table updates daily Bug:T383421 * import needed classes in test * Refactoring: created a wiki class in the metric folde and added tests for it * added comments * Remove test annotations * Update CHANGELOG * Fix typo in CHANGELOG and tests
1 parent 7839f12 commit 7b1f1de

8 files changed

Lines changed: 241 additions & 0 deletions

File tree

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# api
22

3+
4+
## 10x.18.3 - 10 February 2025
5+
- Added new table wiki_daily_metrics
6+
- Added a new Wiki.php class in the metric folder for wiki related metrics
7+
- Added a Job scheduled to run daily and update metrics in the wiki_daily_metric table.
8+
39
## 10x.18.2 - 16 December 2024
410
- Update FAQ link in empty wiki notification email
511

app/Console/Kernel.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,13 @@
1010
use App\Jobs\RequeuePendingQsBatchesJob;
1111
use App\Jobs\SandboxCleanupJob;
1212
use App\Jobs\PollForMediaWikiJobsJob;
13+
use App\Jobs\UpdateWikiDailyMetricJob;
1314
use App\Jobs\UpdateWikiSiteStatsJob;
1415
use App\Jobs\SendEmptyWikiNotificationsJob;
1516
use App\Jobs\CreateQueryserviceBatchesJob;
1617
use App\Jobs\FailStalledEntityImportsJob;
1718
use App\Jobs\UpdateQueryserviceAllowList;
19+
use App\Wiki;
1820
use Illuminate\Console\Scheduling\Schedule;
1921
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
2022

@@ -59,7 +61,10 @@ protected function schedule(Schedule $schedule): void
5961

6062
$schedule->job(new SendEmptyWikiNotificationsJob)->dailyAt('21:00');
6163

64+
$schedule->job(new UpdateWikiDailyMetricJob)->dailyAt('23:00');
65+
6266
$schedule->job(new UpdateQueryserviceAllowList)->weeklyOn(Schedule::MONDAY, '01:00');
67+
6368
}
6469

6570
/**
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php
2+
3+
namespace App\Jobs;
4+
5+
use App\Wiki;
6+
use \App\Metrics\App\WikiMetrics;
7+
use Illuminate\Contracts\Queue\ShouldQueue;
8+
use Illuminate\Foundation\Bus\Dispatchable;
9+
10+
//This job is for the daily measurements of metrics per wikibases.
11+
//This is to help in understanding the purpose of active wikis.
12+
class UpdateWikiDailyMetricJob implements ShouldQueue
13+
{
14+
use Dispatchable;
15+
public int $timeout = 3600;
16+
17+
/**
18+
* Execute the job.
19+
*/
20+
public function handle(): void
21+
{
22+
$wikis= Wiki::withTrashed()->get();
23+
foreach ( $wikis as $wiki ) {
24+
(new WikiMetrics())->saveMetrics($wiki);
25+
}
26+
}
27+
}

app/Metrics/App/WikiMetrics.php

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?php
2+
3+
namespace App\Metrics\App;
4+
5+
use App\Wiki;
6+
use App\WikiDailyMetrics;
7+
8+
class WikiMetrics
9+
{
10+
11+
public function saveMetrics(Wiki $wiki): void
12+
{
13+
$today = now()->format('Y-m-d');
14+
$oldRecord = WikiDailyMetrics::where('wiki_id', $wiki->id)->latest('date')->first();
15+
$todayPageCount = $wiki->wikiSiteStats()->first()->pages ?? 0;
16+
$isDeleted = (bool)$wiki->deleted_at;
17+
if ($oldRecord) {
18+
if ($oldRecord->is_deleted) {
19+
\Log::info("WikiMetrics is deleted, no new record for WikiMetrics ID {$wiki->id}.");
20+
return;
21+
}
22+
if ($oldRecord->pages === $todayPageCount) {
23+
\Log::info("Page count unchanged for WikiMetrics ID {$wiki->id}, no new record added.");
24+
return;
25+
}
26+
}
27+
WikiDailyMetrics::create([
28+
'id' => $wiki->id . '_' . date('Y-m-d'),
29+
'pages' => $todayPageCount,
30+
'is_deleted' => $isDeleted,
31+
'date' => $today,
32+
'wiki_id' => $wiki->id,
33+
]);
34+
\Log::info("New metric recorded for WikiMetrics ID {$wiki->id}");
35+
}
36+
37+
}
38+

app/WikiDailyMetrics.php

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
3+
namespace App;
4+
5+
use Illuminate\Database\Eloquent\Factories\HasFactory;
6+
use Illuminate\Database\Eloquent\Model;
7+
8+
class WikiDailyMetrics extends Model
9+
{
10+
use HasFactory;
11+
12+
protected $table = 'wiki_daily_metrics';
13+
14+
protected $primaryKey = 'id';
15+
16+
public $incrementing = false; // Disable auto-increment
17+
18+
protected $keyType = 'string';
19+
20+
protected $fillable = [
21+
'id',
22+
'wiki_id',
23+
'date',
24+
'pages',
25+
'is_deleted',
26+
];
27+
28+
29+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
3+
use Illuminate\Database\Migrations\Migration;
4+
use Illuminate\Database\Schema\Blueprint;
5+
use Illuminate\Support\Facades\Schema;
6+
7+
return new class extends Migration
8+
{
9+
/**
10+
* Run the migrations.
11+
*/
12+
public function up(): void
13+
{
14+
Schema::create('wiki_daily_metrics', function (Blueprint $table) {
15+
$table->string('id')->primary();
16+
$table->string('wiki_id');
17+
$table->integer('pages');
18+
$table->boolean('is_deleted');
19+
$table->date('date');
20+
$table->timestamps(); // Created at & Updated at
21+
$table->unique(['wiki_id', 'date']);
22+
});
23+
}
24+
25+
/**
26+
* Reverse the migrations.
27+
*/
28+
public function down(): void
29+
{
30+
Schema::dropIfExists('wiki_daily_metrics');
31+
}
32+
};
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
<?php
2+
3+
namespace Tests\Jobs;
4+
5+
use App\Jobs\UpdateWikiDailyMetricJob;
6+
use App\Wiki;
7+
use Carbon\Carbon;
8+
use Illuminate\Foundation\Testing\RefreshDatabase;
9+
use Illuminate\Support\Facades\Queue;
10+
use Tests\TestCase;
11+
12+
class UpdateWikiDailyMetricJobTest extends TestCase
13+
{
14+
15+
use RefreshDatabase;
16+
17+
18+
public function testDispatchJob()
19+
{
20+
Queue::fake();
21+
22+
UpdateWikiDailyMetricJob::dispatch();
23+
24+
Queue::assertPushed(UpdateWikiDailyMetricJob::class);
25+
}
26+
27+
28+
public function testRunJobForAllWikisIncludingDeletedWikis()
29+
{
30+
$activeWiki = Wiki::factory()->create([
31+
'domain' => 'example.wikibase.cloud',
32+
]);
33+
$deletedWiki = Wiki::factory()->create([
34+
'domain' => 'deletedwiki.wikibase.cloud',
35+
]);
36+
$deletedWiki->delete();
37+
38+
(new UpdateWikiDailyMetricJob())->handle();
39+
40+
$this->assertDatabaseHas('wiki_daily_metrics', [
41+
'wiki_id' => $activeWiki->id,
42+
'date' => Carbon::today()->toDateString()
43+
]);
44+
45+
$this->assertDatabaseHas('wiki_daily_metrics', [
46+
'wiki_id' => $deletedWiki->id,
47+
'date' => Carbon::today()->toDateString()
48+
]);
49+
}
50+
51+
}

tests/Metrics/WikiMetricsTest.php

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<?php
2+
3+
namespace Tests\Metrics;
4+
5+
use App\Metrics\App\WikiMetrics;
6+
use App\Wiki;
7+
use App\WikiDailyMetrics;
8+
use Carbon\Carbon;
9+
use Illuminate\Foundation\Testing\RefreshDatabase;
10+
use Tests\TestCase;
11+
12+
class WikiMetricsTest extends TestCase
13+
{
14+
use RefreshDatabase;
15+
16+
17+
public function testSuccessfullyAddRecords()
18+
{
19+
$wiki = Wiki::factory()->create([
20+
'domain' => 'thisfake.wikibase.cloud'
21+
]);
22+
23+
(new WikiMetrics())->saveMetrics($wiki);
24+
// Assert the metric is updated in the database
25+
$this->assertDatabaseHas('wiki_daily_metrics', [
26+
'date' => now()->toDateString()
27+
]);
28+
}
29+
30+
31+
public function testDoesNotAddDuplicateRecordsWithOnlyDateChange()
32+
{
33+
$wiki = Wiki::factory()->create([
34+
'domain' => 'thisfake.wikibase.cloud'
35+
]);
36+
//Insert an old metric value for a wiki
37+
WikiDailyMetrics::create([
38+
'id' => $wiki->id. '_'. Carbon::yesterday()->toDateString(),
39+
'wiki_id' => $wiki->id,
40+
'date' => Carbon::yesterday()->toDateString(),
41+
'pages' => 0,
42+
'is_deleted' => 0
43+
]);
44+
(new WikiMetrics())->saveMetrics($wiki);
45+
46+
//Assert No new record was created for today
47+
$this->assertDatabaseMissing('wiki_daily_metrics', [
48+
'wiki_id' => $wiki->id,
49+
'date' => Carbon::today()->toDateString()
50+
]);
51+
}
52+
}
53+

0 commit comments

Comments
 (0)