Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added datadog extension #442

Merged
merged 3 commits into from
May 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
99 changes: 52 additions & 47 deletions Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,53 +42,54 @@ functions:

### Available layers

| Name | Serverless config (php 8.1) |
|:-------------------|:--------------------------------------|
| AMQP | `${bref-extra:amqp-php-81}` |
| Blackfire | `${bref-extra:blackfire-php-81}` |
| Bsdiff | `${bref-extra:bsdiff-php-81}` |
| Calendar | `${bref-extra:calendar-php-81}` |
| Cassandra | `${bref-extra:cassandra-php-81}` |
| Decimal | `${bref-extra:decimal-php-81}` |
| DS | `${bref-extra:ds-php-81}` |
| Elastic APM | `${bref-extra:elastic-apm-php-81}` |
| GD | `${bref-extra:gd-php-81}` |
| gnupg | `${bref-extra:gnupg-php-81}` |
| GMP | `${bref-extra:gmp-php-81}` |
| gRPC | `${bref-extra:grpc-php-81}` |
| Igbinary | `${bref-extra:igbinary-php-81}` |
| Imagick | `${bref-extra:imagick-php-81}` |
| IMAP | `${bref-extra:imap-php-81}` |
| LDAP | `${bref-extra:ldap-php-81}` |
| Mailparse | `${bref-extra:mailparse-php-81}` |
| MaxMind DB | `${bref-extra:maxminddb-php-81}` |
| Memcache | `${bref-extra:memcache-php-81}` |
| Memcached | `${bref-extra:memcached-php-81}` |
| MongoDB | `${bref-extra:mongodb-php-81}` |
| MsgPack | `${bref-extra:msgpack-php-81}` |
| Newrelic | `${bref-extra:newrelic-php-81}` |
| ODBC Snowflake | `${bref-extra:odbc-snowflake-php-81}` |
| OpenSwoole | `${bref-extra:openswoole-php-81}` |
| Oracle | `${bref-extra:oci8-php-80}` |
| Pcov | `${bref-extra:pcov-php-81}` |
| PostgreSQL | `${bref-extra:pgsql-php-81}` |
| RdKafka | `${bref-extra:rdkafka-php-81}` |
| Redis (phpredis) | `${bref-extra:redis-php-81}` |
| Redis-Igbinary | `${bref-extra:redis-igbinary-php-81}` |
| Relay | `${bref-extra:relay-php-81}` |
| Scout APM | `${bref-extra:scoutapm-php-81}` |
| Scrypt | `${bref-extra:scrypt-php-81}` |
| SPX | `${bref-extra:spx-php-81}` |
| SSH2 | `${bref-extra:ssh2-php-81}` |
| Swoole | `${bref-extra:swoole-php-81}` |
| Symfony Runtime | `${bref-extra:symfony-runtime-php-81}`|
| Microsoft SQLSRV | `${bref-extra:sqlsrv-php-81}` |
| Tideways | `${bref-extra:tideways-php-81}` |
| Tidy | `${bref-extra:tidy-php-81}` |
| UUID | `${bref-extra:uuid-php-81}` |
| Xdebug | `${bref-extra:xdebug-php-81}` |
| Xlswriter | `${bref-extra:xlswriter-php-81}` |
| Yaml | `${bref-extra:yaml-php-81}` |
| Name | Serverless config (php 8.1) |
|:-----------------|:---------------------------------------|
| AMQP | `${bref-extra:amqp-php-81}` |
| Blackfire | `${bref-extra:blackfire-php-81}` |
| Bsdiff | `${bref-extra:bsdiff-php-81}` |
| Calendar | `${bref-extra:calendar-php-81}` |
| Cassandra | `${bref-extra:cassandra-php-81}` |
| Datadog | `${bref-extra:datadog-php-81}` |
| Decimal | `${bref-extra:decimal-php-81}` |
| DS | `${bref-extra:ds-php-81}` |
| Elastic APM | `${bref-extra:elastic-apm-php-81}` |
| GD | `${bref-extra:gd-php-81}` |
| gnupg | `${bref-extra:gnupg-php-81}` |
| GMP | `${bref-extra:gmp-php-81}` |
| gRPC | `${bref-extra:grpc-php-81}` |
| Igbinary | `${bref-extra:igbinary-php-81}` |
| Imagick | `${bref-extra:imagick-php-81}` |
| IMAP | `${bref-extra:imap-php-81}` |
| LDAP | `${bref-extra:ldap-php-81}` |
| Mailparse | `${bref-extra:mailparse-php-81}` |
| MaxMind DB | `${bref-extra:maxminddb-php-81}` |
| Memcache | `${bref-extra:memcache-php-81}` |
| Memcached | `${bref-extra:memcached-php-81}` |
| MongoDB | `${bref-extra:mongodb-php-81}` |
| MsgPack | `${bref-extra:msgpack-php-81}` |
| Newrelic | `${bref-extra:newrelic-php-81}` |
| ODBC Snowflake | `${bref-extra:odbc-snowflake-php-81}` |
| OpenSwoole | `${bref-extra:openswoole-php-81}` |
| Oracle | `${bref-extra:oci8-php-80}` |
| Pcov | `${bref-extra:pcov-php-81}` |
| PostgreSQL | `${bref-extra:pgsql-php-81}` |
| RdKafka | `${bref-extra:rdkafka-php-81}` |
| Redis (phpredis) | `${bref-extra:redis-php-81}` |
| Redis-Igbinary | `${bref-extra:redis-igbinary-php-81}` |
| Relay | `${bref-extra:relay-php-81}` |
| Scout APM | `${bref-extra:scoutapm-php-81}` |
| Scrypt | `${bref-extra:scrypt-php-81}` |
| SPX | `${bref-extra:spx-php-81}` |
| SSH2 | `${bref-extra:ssh2-php-81}` |
| Swoole | `${bref-extra:swoole-php-81}` |
| Symfony Runtime | `${bref-extra:symfony-runtime-php-81}` |
| Microsoft SQLSRV | `${bref-extra:sqlsrv-php-81}` |
| Tideways | `${bref-extra:tideways-php-81}` |
| Tidy | `${bref-extra:tidy-php-81}` |
| UUID | `${bref-extra:uuid-php-81}` |
| Xdebug | `${bref-extra:xdebug-php-81}` |
| Xlswriter | `${bref-extra:xlswriter-php-81}` |
| Yaml | `${bref-extra:yaml-php-81}` |

### Blackfire installation

Expand Down Expand Up @@ -142,6 +143,10 @@ in your `serverless.yaml` in order to tell unixODBC to load the required ini fil

Read [the New Relic tutorial](docs/newrelic.md).

### Datadog

Read [the Datadog tutorial](docs/datadog.md).

## Docker images

There are Docker images for every layer. They are updated on every push to master
Expand Down
86 changes: 86 additions & 0 deletions docs/datadog.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
### Datadog installation

This layer enables the installation of only the Datadog PHP extension.

To use the extension, you must also install the Datadog agent.
You can achieve this by installing another Datadog Lambda Extension layer.
For more information see https://docs.datadoghq.com/serverless/installation/python/?tab=custom the "Install the Datadog Lambda Extension" section.

If you are running an x86-based Lambda in AWS commercial regions, use the following ARN:
`arn:aws:lambda:<AWS_REGION>:464622532012:layer:Datadog-Extension:<version>`

If you are running an ARM-based Lambda in AWS commercial regions, use the following ARN:
`arn:aws:lambda:<AWS_REGION>:464622532012:layer:Datadog-Extension-ARM:<version>`

## Configuration

After installing the layer and the agent, you must configure the Datadog extension by adding the following key/value pair to a Lambda environment variable:

- `DD_ENV=<enviroment>`
- `DD_SERVICE=<service>`
- `DD_SITE=<datadoghq.eu|datadoghq.com>` (depending on your Datadog account region)
- `DD_API_KEY=<api_key>`
- `DD_SERVICE=<your service name>`
- `DD_VERSION=<your service version>`

For more details about the configuration, see https://docs.datadoghq.com/tracing/trace_collection/library_config/php/

You should also consider adding similar AWS tags to your Lambda function to link APM and Infrastructure data together using the tag/value syntax:

- `Env=<the same as DD_ENV>`
- `Service=<the same as DD_SERVICE>`
- `Team=<the team name>` (use `a-z0-9\-` pattern)
- `Tier=<A|B|C|...>` (to indicate how important the service is)

Find more about infrastructure tagging:
- https://www.datadoghq.com/blog/tagging-best-practices/
- https://learn.datadoghq.com/courses/tagging-best-practices (online course)
- Enroll in free technical sessions at https://www.datadoghq.com/technical-enablement/sessions/

## Custom instrumentation

DataDog works out of the box with the php-xx-fpm runtime. However, if you are using the php-xx runtime and BREF_LOOP_MAX>1, you must add custom instrumentation.
Otherwise, DataDog will wait until the end of a loop and only send one trace.
To add custom instrumentation, create an `instrumentation.php` file and add the following code:

```php
<?php

\DDTrace\trace_method(
'Bref\Runtime\Invoker',
'invoke',
function (\DDTrace\SpanData $span, $args, $ret, $exception) {
$span->service = getenv('DD_SERVICE');
$span->type = \DDTrace\Type::CLI;
$span->name = 'invoke';
}
);
```

This code will enable you to see all traces.

*do not forget to add `instrumentation.php` to a `composer.json` file

For EventBridge Lambdas, add the following code to the function above:

```php
<?php
if ($args[0] instanceof \Bref\Event\EventBridge\EventBridgeEvent) {
$span->resource = $args[0]->getDetailType();
}
```

This code will name your traces with the EventBridge event name.

For more information about custom instrumentation, refer to the following resources:

- https://github.com/DataDog/dd-trace-php/blob/master/examples/long-running/long-running-script.php
- https://docs.datadoghq.com/tracing/trace_collection/custom_instrumentation/php/?tab=currentspan
- to link traces with a parent one: https://docs.datadoghq.com/tracing/trace_collection/trace_context_propagation/php/

## service.datadog.yaml

Consider also creating a `service.datadog.yaml` file in the root of your project.
It will give you more control over the traces and ability to add links to documentation and contact information.

To find more: https://www.datadoghq.com/blog/manage-service-catalog-categories-with-service-definition-json-schema/
33 changes: 33 additions & 0 deletions layers/datadog/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
ARG PHP_VERSION
ARG BREF_VERSION
FROM bref/build-php-$PHP_VERSION:$BREF_VERSION AS ext

ENV DDTRACE_BUILD_DIR=${BUILD_DIR}/ddtrace

RUN set -xe; \
mkdir -p ${DDTRACE_BUILD_DIR}; \
curl -Ls -o ${DDTRACE_BUILD_DIR}/datadog-setup.php \
https://github.com/DataDog/dd-trace-php/releases/latest/download/datadog-setup.php

WORKDIR ${DDTRACE_BUILD_DIR}

RUN php datadog-setup.php --php-bin=all --enable-profiling

RUN cp "$(php-config --extension-dir)/ddtrace.so" /tmp/ddtrace.so && \
cp "$(php-config --extension-dir)/datadog-profiling.so" /tmp/datadog-profiling.so && \
cp "$(php-config --ini-dir)/98-ddtrace.ini" /tmp/ext.ini

RUN sed -i 's/extension = ddtrace\.so/extension = \/opt\/bref-extra\/ddtrace.so/' /tmp/ext.ini && \
sed -i 's/extension = datadog-profiling\.so/extension = \/opt\/bref-extra\/datadog-profiling.so/' /tmp/ext.ini && \
sed -i 's/;datadog\.agent_host.*$/datadog\.agent_host = 127.0.0.1/' /tmp/ext.ini && \
sed -i 's/^.*datadog\.appsec\.enabled.*$/datadog.appsec.enabled = Off/' /tmp/ext.ini && \
sed -i 's/datadog\.profiling\.enabled = On/datadog.profiling.enabled = 1/' /tmp/ext.ini

# Build the final image with just the files we need
FROM scratch

# Copy things we installed to the final image
COPY --from=ext /tmp/ddtrace.so /opt/bref-extra/ddtrace.so
COPY --from=ext /tmp/datadog-profiling.so /opt/bref-extra/datadog-profiling.so
COPY --from=ext /tmp/ext.ini /opt/bref/etc/php/conf.d/98-ddtrace.ini
COPY --from=ext /opt/datadog/ /opt/datadog
7 changes: 7 additions & 0 deletions layers/datadog/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"php": [
"80",
"81",
"82"
]
}
8 changes: 8 additions & 0 deletions layers/datadog/test.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?php

if (!class_exists($class = \DDTrace\SpanData::class)) {
echo sprintf('FAIL: Class "%s" does not exist.', $class).PHP_EOL;
exit(1);
}

exit(0);