Giter Site home page Giter Site logo

googlecloudplatform / stackdriver-debugger-php-extension Goto Github PK

View Code? Open in Web Editor NEW
24.0 11.0 17.0 112 KB

Investigate your code’s behavior in production

Home Page: https://cloud.google.com/debugger/

License: Apache License 2.0

M4 0.26% C 54.08% C++ 1.42% PHP 40.80% Shell 3.09% JavaScript 0.21% HTML 0.14%

stackdriver-debugger-php-extension's Introduction

Stackdriver Debugger PHP Extension CircleCI

Stackdriver Debugger is a free, open-source way to debug your running application without requiring a redeployment.

This library allows you to set breakpoints in your running application that conditionally capture local variable state, stack traces, and more. This library can work in conjunction with the PHP library google/cloud-debugger in order to send collected data to a backend storage server.

Compatibilty

This extension has been built and tested on the following PHP versions:

  • 7.2.x (ZTS and non-ZTS)
  • 7.1.x (ZTS and non-ZTS)
  • 7.0.x (ZTS and non-ZTS)

Installation

Download from PECL

Install the extension using the pecl CLI tool:

pecl install stackdriver_debugger-alpha

Usage

Snapshots

A snapshot captures the current stacktrace at the specified file and line, including all local variables at each point of the stacktrace. These snapshots do not stop the execution of your application. Each snapshot should only be captured ONCE (although snapshots may be captured in parallel requests).

The general workflow for using snapshots is to register the snapshot as soon as possible in your application, then fetch the list at the end of the request for reporting.

Registering Snapshots

To register a snapshot for capture, use the stackdriver_debugger_add_snapshot function:

/**
 * Register a snapshot for recording.
 *
 * @param string $filename
 * @param int $line
 * @param array $options [optional] {
 *      Configuration options.
 *
 *      @type string $snapshotId Identifier for this snapshot. Defaults to a
 *            randomly generated value.
 *      @type string $condition If provided, this PHP statement will be
 *            executed at the snapshot point in that execution context. If the
 *            value is truthy, then the snapshot will be evaluated.
 *      @type array $expressions An array of additional statements to execute
 *            in the execution context that are captured along with the local
 *            variables in scope.
 *      @type string $sourceRoot
 *      @type callable $callback
 * }
 */
function stackdriver_debugger_add_snapshot($filename, $line, $options);

Fetching Captured Snapshots

To retrieve all captured snapshots for this request, use the stackdriver_debugger_list_snapshots function:

/**
 * Return the collected list of debugger snapshots that have been collected for
 * this request.
 *
 * @return array
 */
function stackdriver_debugger_list_snapshots();

This function returns an array of snapshots. Each snapshot is an associative array with the following fields:

  • id - string - the identifier of the snapshot
  • stackframes - array - array of stackframe data
  • evaluatedExpressions - array - associative array of expression => expression result

Each stackframe is an associative array with the following fields:

  • function - string - the current function, if any
  • filename - string - file being executed
  • line - string - line being executed
  • locals array - array of local variables in the current scope

Each variable is an associative array with the following fields:

  • name - string - the name of the local variable
  • value - mixed - a copy of the variable at the captured point in time

Logpoints

A logpoint creates a message for logging at the specified file and line. The message are executed in the current execution scope to allow you to utilize local variables. Logpionts will be executed EVERY time that file and line are hit.

Registering Logpoints

To register a logpoint for capture, use the stackdriver_debugger_add_logpoint function:

/**
 * Register a logpoint for recording.
 *
 * @param string $filename
 * @param int $line
 * @param string $logLevel
 * @param string $format
 * @param array $options [optional] {
 *      Configuration options.
 *
 *      @type string $snapshotId
 *      @type string $condition
 *      @type array $expressions
 *      @type string $sourceRoot
 *      @type callable $callback
 * }
 */
function stackdriver_debugger_add_logpoint($filename, $line, $logLevel, $format, $options);

Fetching Captured Logpoint Messages

To retrieve all captured logpoint messages, use the stackdriver_debugger_list_logpoints function:

/**
 * Return the collected list of logpoint messages that have been collected for
 * this request.
 *
 * @return array
 */
function stackdriver_debugger_list_logpoints();

This function returns an array of messages. Each message is an array with the following fields:

  • filename - string - full path to file
  • line - int - line in the file that was executed
  • message - string - output message
  • timestamp - int - UNIX timestamp
  • level - string - log level

Configuration

Max Time Limit

By default, we restrict time spent in the debugger to 10ms per request, but will allow the running snapshot or logpoint to finish. Any future snapshots or logpoints within the request will not trigger.

You can customize this limit by setting the ini config stackdriver_debugger.max_time:

# in php.ini
stackdriver_debugger.max_time=50

or

ini_set('stackdriver_debugger.max_time', '50');

Whitelisting Function Calls in Conditions and Evaluated Expressions

Setting a snapshot or logpoint should not affect the state of any application. By default, we disallow any unknown function calls that could potentially modify the state of your application.

You can add additional function calls to this list by setting the ini config stackdriver_debugger.function_whitelist:

# in php.ini
stackdriver_debugger.function_whitelist="foo,bar,MyClass::function"
ini_set('stackdriver_debugger.function_whitelist', 'foo,bar,MyClass::function');

Note that all function names specified here must be declared with their full namespace if applicable.

Design

For more information on the design of this project, see Design Document.

Versioning

You can retrieve the version of this extension at runtime.

/**
 * Return the current version of the stackdriver_debugger extension
 *
 * @return string
 */
function stackdriver_debugger_version();

This library follows Semantic Versioning.

Please note it is currently under active development. Any release versioned 0.x.y is subject to backwards incompatible changes at any time.

GA: Libraries defined at a GA quality level are stable, and will not introduce backwards-incompatible changes in any minor or patch releases. We will address issues and requests with the highest priority.

Beta: Libraries defined at a Beta quality level are expected to be mostly stable and we're working towards their release candidate. We will address issues and requests with a higher priority.

Alpha: Libraries defined at an Alpha quality level are still a work-in-progress and are more likely to get backwards-incompatible updates.

Contributing

Contributions to this library are always welcome and highly encouraged.

See CONTRIBUTING for more information on how to get started.

Releasing

See RELEASING for more information on releasing new versions.

License

Apache 2.0 - See LICENSE for more information.

stackdriver-debugger-php-extension's People

Contributors

chingor13 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

stackdriver-debugger-php-extension's Issues

Fix compilation warnings

stackdriver_debugger_logpoint.c and stackdriver_debugger_snapshot.c both rely on zend_exceptions.h

Allow whitelisting class methods

In most modern PHP applications the majority of class fields will be private or protected and there will be a set of getters to access those fields. This makes it difficult to use expressions in snapshots or logpoints because many times the information that interests you will be held in a private or protected field, so you will not be able to use a expression like $object->privateMember because you will not have access. By default you cannot call any method in an object and there is no way to whitelist method calls.

We should have a way to whitelist method calls so that we can use expressions like $object->getPrivateMember(). By default no method call should be allowed but if we know that some of them are safe we should be able to whitelist them, the same way that we do for generic functions

Add tests for memory leaks

Run tests against php with debug enabled and the automated tests should report failures for memory leaks.

Send snapshots and logpoints ASAP

Ideally, we'd like to see the snapshot and logpoint data as soon as it's available.

We can register a callback function when registering a snapshot/logpoint and let that callback immediately report results. As a side benefit, we then wouldn't need to keep a copy of the local variables until the end of the request.

Better handling of superglobals

There are two ways to improve superglobal handling:

  1. if you layer multiple require/include calls before a snapshot is generated, then each require/include is as if a function was called in the global state and the same superglobals $_POST, $_SERVER etc are attached to each stack frame. Best idea would be to add the superglobals only on the outermost stackframe.

  2. The $GLOBALS variable is exported in every non-scoped stackframe (require, include) and duplicates the same data from $_POST, $_SERVER all over again. Best would be to include only $GLOBALS, which in turn includes all superglobals on the outermost stackframe, and skip the $_POST, ... etc ones from being included.

Improve cache clearing with OPCache

We currently expect to clear OPCache on every file that has a breakpoint. We can optimize this by maintaining a history of which breakpoints have been set in a file and only clear the opcode cache for files that need to be cleared.

Allow using regular expressions in whitelisted function list

It can be useful to allow whitelisting functions by using a regex for the function name, this should allow us to have to add a long list of functions if they all share some commonality in their name. Specially useful to whitelist a range of static class functions, for example all DateTime static functions by using a regex like /^DateTime::/

Return an object id when capturing an array

PHP user space can't quickly tell if 2 arrays are the same. Therefore, we cannot utilize the variable table to optimize reporting. The c code should be able to return an "object id" (most likely an address pointer) which the variable table can use to de-dup arrays.

test failure on 32-bit

Test suite ok on 64-bit

On 32-bit

TEST 21/61 [tests/logpoints/memory_limit.phpt]
========DIFF========
005+ logpoint: INFO - Logpoint hit!
========DONE========
FAIL Stackdriver Debugger: Logpoints should not spend more than 10MB [tests/logpoints/memory_limit.phpt] 

Invalid expressions should not cause the php interpreter to fail

Currently, if you enter an invalid expression (for example bad as the expression for a snapshot or {bad} as the message for a logpoint) the php interpreter will fail, either throwing an exception or a segmentation fault, when it reaches the breakpoint

This is very bad news for running the debugger in production. You can easily break production by adding a breakpoint (snapshot or logpoint) with invalid expressions.

The behaviour should be the same as the current behaviour for conditions. If you enter an invalid condition this is just ignored. Or perhaps some kind of error is recorded for snapshots and logpoints, but never crash the app

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.