Laravel/PHP Quick Start [Impact Analysis]

This guide is meant to get you started using Impact Analysis with Codecov as quickly as possible on laravel projects

Prerequisites

In order to get started, you will need a repository that is:

  1. A repository that is active on Codecov
  2. An Impact Analysis token obtainable from your repository's settings page in the Codecov UI.
  3. PHP version >=7.4 applications using the Laravel Framework
  4. pcov installed as a PHP extension (see Installation below)

Getting Started


Step 1: Get your Impact analysis token

In your repository settings page on Codecov, copy the Impact analysis token to be used when uploading telemetry reports

1051

Step 2: Update your dependencies

Add Project Level Dependencies

Add the following dependency via composer:

composer require codecov/laravel-codecov-opentelemetry

As of version v0.1.0, HTTP functionality has switched from Guzzle to HTTPlug to allow for more streamlined integration into applications. Therefore, you must bring your own HTTP client implementation to use this library. You can read more about this here, but if you're not using an http client in your application already, it is recommended to do the following:

composer require php-http/curl-client guzzlehttp/psr7 php-http/message

Otherwise, it is recommend to consult the HTTPlug documentation.

Add the pcov System Level Dependency

🚧

pcov is Required

In order to properly function, Impact Analysis for PHP/Laravel requires the installation of the pcov PHP extension.

In order to sample line execution data, some configuration is required. Specifically, the PCOV extension must be installed and enabled in your php.ini file.

Enabling pcov is dependent on the underlying system where you are running PHP. The below example uses Alpine with PHP 8.0 in a Docker image, but others are also supported:

FROM alpine:3.14

RUN apk update && apk upgrade && \
    #...your dependencies here
    php8-dev gcc make

# Symling php8 => php
RUN ln -s /usr/bin/php8 /usr/bin/php
RUN ln -s /usr/bin/phpize8 /usr/bin/phpize
RUN ln -s /usr/bin/php-config8 /usr/bin/php-config

# Install pcov
RUN wget https://github.com/FriendsOfPHP/pickle/releases/download/v0.6.0/pickle.phar && mv pickle.phar /usr/local/bin/pickle && chmod +x /usr/local/bin/pickle
RUN pickle install pcov
RUN echo "extension=pcov.so" > /etc/php8/conf.d/php-ext-pcov.ini
RUN echo "pcov.enabled=1" >> /etc/php8/conf.d/php-ext-pcov.ini

While this shows one example, the basic steps are as follows:

  1. Install the relevant system level dependencies for php and pickle
  2. Symlink your PHP version to the canonical defaults (if required)
  3. Install pickle
  4. Instal pcov via pickle
  5. Enable the pcov extension via .ini configuration.

If your system already leverages another mechanism to install PHP extensions, it is recommended to use that mechanism instead of pickle.

Other examples of how to integrate pcov can be seen here.

Step 3: Configure the Package

This package is currently intended to be used as a Laravel route middleware. After installing the package you should add it to your $routeMiddleware in app/Http/Kernel.php as follows:

protected $routeMiddleware = [
        'auth' => \App\Http\Middleware\Authenticate::class,
        'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
        //...other middleware
        'codecov.insights' => \Codecov\LaravelCodecovOpenTelemetry\Middleware\Trace::class,
    ];

Once added there you can apply the middleware to various routes in your routes/web.http file as follows:

Route::middleware(['codecov.insights'])->group(function () {
        //...routes
    });

or any other mechanism by which you prefer to add middleware.

Configuration Details

Environment Variables

This package provides a configuration file that can be published via

php artisan vendor:publish

and selecting the Codecov\\LaravelCodecovOpenTelemetry package from the list that appears.

The following settings are available, and more information can be found in the configuration file:

NameEnvironment Variable NameDefaultDescriptionRequired
service_nameCODECOV_OTEL_SERVICE_NAMElaravel-codecov-opentelemetryThe name of the service you are profiling. Kebab or snake case is recommendedNo
codecov_hostCODECOV_OTEL_HOSThttps://api.codecov.ioThe host where profiling data will be sent. Override with self-hosted URL if you are a Codecov self-hosted customer.No
profiling_tokenCODECOV_OTEL_ PROFILING_TOKENnullThe token used to identify this repository with Codecov.Yes
execution_environmentCODECOV_OTEL_ ENVIRONMENTAPP_ENV` if defined, otherwise null.Environment where the profiled service is running. APP_ENV default should work for most cases.Yes, if APP_ENV is not supplied
profiling_idCODECOV_OTEL_PROFILING_IDCOMMIT_SHA if defined, otherwise "default"A unique identifier for the specific release. Commit SHA is recommended, but anything can be provided, such as semver.
tracked_spans_sample_rateCODECOV_OTEL_ TRACKED_SPANS_SAMPLE_RATE10Percentage of spans that are sampled with execution data. Note that sampling execution data does incur some performance penalty, so 10% is recommended for most services.No
untracked_spans_sample_rateCODECOV_OTEL_ UNTRACKED_SPANS_SAMPLE_RATE10Percentage of spans that are sampled without execution data. These spans incur a much smaller performance penalty, but do not provide as robust a data set to Codecov, resulting in some functionality being limited.No
force_sync_requestsCODECOV_OTEL_ FORCE_SYNC_REQUESTSfalseForces the HTTP client to make synchronous requests to the Codecov API, even if the underlying client supports asynchronous behavior. If the client does not support asynchronous requests, this setting is ignored.No

Step 4: Update the codecov.yaml configuration

In order to get Impact Analysis data in your pull requests, add the following lines of code to your codecov.yaml file

comment:
  layout: "diff,flags,tree,betaprofiling"
  show_critical_paths: true

Commit the above code and run your code in production as usual. Note that it may take 30 minutes for the changes to propagate.


Seeing Impact Analysis in your pull requests

After you have followed the steps above, you will need to run the code in a production-like environment. To see changes in your pull requests, make a code change on

You should be able to see two differences. The first notates Critical on files that have code run frequently in production that are also being changed. The second shows API endpoints that are affected by the pull request.

485

If you are making changes to code that is not deemed critical, you should still see the following in your pull request comment from Codecov.

324

Performance Implications

Using line execution in a production system does incur a performance penalty. However, this penalty may be fairly negligible depending on your use case.

A rough benchmark using Apache Benchmark was generated by visiting the same endpoint of the same Laravel application with line execution sampling enabled and disabled. Apache Benchmark was provided via a Dockerized implementation and was executed with the following command:

docker run --rm jordi/ab -v 2 -n 100 -c 10 http://<path-to-application>/login

This command was run against the same application with pcov line execution enabled and disabled. In each case the following environment variables were used:

# enabled at 10% sampling
CODECOV_OTEL_ENABLED=true
CODECOV_OTEL_TRACKED_SPANS_SAMPLE_RATE=10
CODECOV_OTEL_UNTRACKED_SPANS_SAMPLE_RATE=10
# disabled
CODECOV_OTEL_ENABLED=false

Results are as follows:

metricdisabledenabled @ 10%
Time taken for tests (s)8.45913.284
Requests per second11.827.53
Time per request (ms)84.59132.835

While a performance penalty is indicated, it will only be for those 10% of endpoints that are actively sampled. 90% of requests in this case will incur no performance penalty. Furthermore, if a service is heavily trafficked, reducing sampling to 1% may be sufficient.

Also note that performance improvement is a work in progress, and we expect the above metrics to more closely align with subsequent releases.

Troubleshooting

🚧

Laravel Projects Frequently Require Path Fixing

Pay special attention to the section below, as Laravel apps quite often require path fixing to function properly.

Not seeing critical changes? You may need to add path fixes to your codecov.yml configuration.

profiling:
  fixes:
    - "before/::after/"  # move path   e.g., "before/path" => "after/path"
    - "::after/"         # move root   e.g., "path/" => "after/path/"
    - "before/::"        # reduce root e.g., "before/path/" => "path/"

You can also check out our example repository to see a complete setup.

Due to their folder structure and how runtime execution data is collected, Laravel apps almost always require a path fix to function properly. If your Laravel app is setup using the default configuration, the fix is likely:

profilling:
  fixes:
  - "::app/"

if the Laravel app is the root of your repo. If it is not the root, then the fix must include all paths up to the app directory. Consider a repository with the following path to the app directory: myexampleapp/example/app. In this case the fix would be as follows:

profilling:
  fixes:
  - "::example/app/"

In general, the fix should include all directories except the root directory name and include all directories to the up to the app folder.