composer require xbnz/mtr
// Optionally configure DI (Laravel example)
class AppServiceProvider extends Provider
{
public function register()
{
$this->app->bind(MTR::class, function (Application $app) {
return MTR::build(Config::get('services.mtr_options'), $app->make(LoggerInterface::class));
});
}
}
// services.php
return [
// ...
'mtr_options' => new \Xbnz\Mtr\MtrOptionsConfigDto(...)
]
You should not disable the 'report wide' or 'json' options. The package will cease to work.
use Xbnz\Mtr;
public function __construct(private MTR $mtr)
{}
// Or without DI...
public function __construct()
{
$this->mtr = Mtr::build(new MtrOptionsConfigDto(...), new Logger);
}
public function example()
{
// Consider a high timeout value for large scans.
// Async threads above 50 might cause inaccuracies in RTT statistics.
$results = $this->mtr->withIp('1.1.1.1', '8.8.8.8')->wrap($consoleTimeout, $concurrentProcesses);
// OR
$results = $this->mtr->withIp(...['1.1.1.1', '8.8.8.8'])->wrap($consoleTimeout, $concurrentProcesses);
// OR
$results = $this->mtr->withIp('1.1.1.1')->wrap($consoleTimeout, $concurrentProcesses);
// OR
$results = $this->mtr->withIp(995738574453)->wrap($consoleTimeout, $concurrentProcesses);
// OR
$results = $this->mtr->withIp('google.com')->wrap($consoleTimeout, $concurrentProcesses);
// OR
$results = $this->mtr->withIp(0x1294812)->wrap($consoleTimeout, $concurrentProcesses);
Assert::containsOnlyInstancesOf(
MtrResult::class,
$results
);
/**
* If last hop of MTR !== supplied IP, the target is dead.
* In most circumstances, you'd want to reject dead targets.
* You might still want to see the hops for a dead target, so the default policy is not to reject.
*/
$aliveTargetHopPairs = $results
->reject(fn($result) => $result->targetDown())
->map(fn($result) => [$result->targetHost => $result->hops]);
->each(fn($targetWithHops) => Assert::containsOnlyInstancesOf(MtrHopDto::class, $targetWithHops));
$aliveTargetHopPairs
->each(function ($hops, $ip) {
if ($hops->last()->packetLoss > 5) {
$this->logger->log("Target {$ip}, hop {$hops->last()->hopPositionCount} has {$hops->last()->packetLoss}% loss")
}
});
}
The raw()
method will return an unprocessed result set from MTR. This will also allow you to hook into each asynchronous
process, which is useful for long-running processes.
For example, you might want to keep track of each IP that is processed, like so.
public function handle(MTR $mtr)
{
// Thousands of IPs
$mtr->withIp('1.1.1.1/20')
->raw(callable: function (ForkSerializableProcessDto $dto) {
dump($dto->host . PHP_EOL);
})
}