Skip to content

Commit

Permalink
Merge pull request #854 from newrelic/dev
Browse files Browse the repository at this point in the history
Release 10.19
  • Loading branch information
lavarou authored Mar 15, 2024
2 parents 51c1140 + c9c6fba commit 9caf27b
Show file tree
Hide file tree
Showing 930 changed files with 1,286 additions and 295,567 deletions.
81 changes: 20 additions & 61 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
# The top level Makefile
#
GCOV ?= gcov
GO ?= go
SHELL = /bin/bash
GCOVR ?= gcovr
GIT ?= git
Expand All @@ -20,17 +19,6 @@ include make/php_versions.mk
# Include the secrets file if it exists, but if it doesn't, that's OK too.
-include make/secrets.mk

# Configure an isolated workspace for the Go daemon.
export GOPATH=$(CURDIR)
export GO15VENDOREXPERIMENT=1
# Needed for Go > 1.11 to avoid building with modules by default
export GO111MODULE=auto

# GOBIN affects the behavior of go install, ensure it is unset.
unexport GOBIN

GOFLAGS := -ldflags '-X newrelic/version.Number=$(AGENT_VERSION) -X newrelic/version.Commit=$(GIT_COMMIT) -X newrelic/secrets.NewrelicCollectorHost=$(NEWRELIC_COLLECTOR_HOST) -X newrelic/secrets.NewrelicLicenseKey=$(NEWRELIC_LICENSE_KEY) -X newrelic/secrets.NewrelicCollectorKeys=$(NEWRELIC_COLLECTOR_KEYS) -X newrelic/secrets.NewrelicAccountId=$(ACCOUNT_supportability) -X newrelic/secrets.NewrelicAppId=$(APP_supportability)' $(GO_TAGS)

GCOVRFLAGS += -e "agent/tests/*" -e "axiom/tests/*" -e ".*\.h" -o

#
Expand Down Expand Up @@ -170,68 +158,39 @@ agent-valgrind: agent/Makefile
$(MAKE) -C agent valgrind

#
# Build the daemon and related utilities
#

#
# Minimum required version of Go is 1.5.
# Daemon rules
# defers to behavior defined in daemon/Makefile once $GOBIN has been set
#
# This is defined as a rule that other rules that require Go can depend upon.
# We don't want to require Go for a general build primarily to make the PHP
# agent easier to use as a component within the C agent.
#
.PHONY: go-minimum-version
go-minimum-version:
@if $(GO) version | awk '/go1.[012345678][\. ]/ { exit 1 }'; then \
true; \
else \
echo -n 'Go 1.9 or newer required; found '; $(GO) version; false; \
fi

DAEMON_TARGETS := $(addprefix bin/,client daemon integration_runner stressor)
# Configure the target directory for go install
export GOBIN=$(CURDIR)/bin

# Delete Go binaries before each build to force them to be re-linked. This
# ensures the version and commit variables are set correctly by the linker.
#
# The bin directory is also the target directory for the installer,
# which we need to be careful to leave in place. Therefore, the names of the
# Go binaries are made explicit. If we used a conventional `cmd` subdirectory
# for commands, we could use `go list` to determine the names.
.PHONY: daemon
daemon: go-minimum-version daemon-protobuf Makefile | bin/
@rm -rf $(DAEMON_TARGETS)
@$(GO) install $(GOFLAGS) ./...
daemon:
$(MAKE) -C daemon

# The -race flag enables the inegrated Go race detector. Output to stderr
.PHONY: daemon_race
daemon_race: go-minimum-version daemon-protobuf Makefile | bin/
@rm -rf $(DAEMON_TARGETS)
@$(GO) install -race $(GOFLAGS) ./...
daemon_race:
$(MAKE) -C daemon race

.PHONY: daemon_test
daemon_test: go-minimum-version daemon-protobuf
@$(GO) test $(GOFLAGS) ./...
daemon_test:
$(MAKE) -C daemon test

.PHONY: daemon_bench
daemon_bench: go-minimum-version daemon-protobuf
@$(GO) test $(GOFLAGS) -bench=. ./...
daemon_bench:
$(MAKE) -C daemon bench

.PHONY: daemon_integration
daemon_integration: go-minimum-version daemon-protobuf
$(MAKE) INTEGRATION_TAGS=1 go-minimum-version
@$(GO) test $(GOFLAGS) ./...
daemon_integration:
$(MAKE) -C daemon integration

DAEMON_COV_FILE = daemon_coverage.out
.PHONY: daemon_cover
daemon_cover: go-minimum-version daemon-protobuf
@rm -f $(DAEMON_COV_FILE)
@$(GO) test -coverprofile=$(DAEMON_COV_FILE) $(GOFLAGS) ./...
$(GO) tool cover -html=$(DAEMON_COV_FILE)
@rm -f $(DAEMON_COV_FILE)
daemon_cover:
$(MAKE) -C daemon cover

bin/integration_runner:
@echo "Building bin/integration_runner"
@$(GO) install $(GOFLAGS) integration_runner
$(MAKE) -C daemon integration_runner

# Note that this rule does not require the Go binary, and therefore doesn't
# depend on go-minimum-version.
Expand Down Expand Up @@ -317,14 +276,14 @@ axiom-clean:
# Before running this script, make sure the location of protoc-gen-go is in
# your $PATH.
.PHONY: daemon-protobuf
daemon-protobuf: src/newrelic/infinite_tracing/com_newrelic_trace_v1/v1.pb.go
daemon-protobuf: daemon/internal/newrelic/infinite_tracing/com_newrelic_trace_v1/v1.pb.go

src/newrelic/infinite_tracing/com_newrelic_trace_v1/v1.pb.go: protocol/infinite_tracing/v1.proto
daemon/internal/newrelic/infinite_tracing/com_newrelic_trace_v1/v1.pb.go: protocol/infinite_tracing/v1.proto
$(MAKE) vendor # Only build vendor stuff if v1.proto has changed. Otherwise
# this rule will be triggered every time the daemon is built.
$(VENDOR_PREFIX)/bin/protoc \
-I=./protocol/infinite_tracing \
--go_out="paths=source_relative,plugins=grpc:src/newrelic/infinite_tracing/com_newrelic_trace_v1" \
--go_out="paths=source_relative,plugins=grpc:daemon/internal/newrelic/infinite_tracing/com_newrelic_trace_v1" \
protocol/infinite_tracing/v1.proto

#
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
10.18.0
10.19.0
1 change: 1 addition & 0 deletions agent/Makefile.frag
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ TEST_BINARIES = \
tests/test_pdo_mysql \
tests/test_pdo_pgsql \
tests/test_pgsql \
tests/test_php_error \
tests/test_php_execute \
tests/test_php_minit \
tests/test_php_stack \
Expand Down
52 changes: 52 additions & 0 deletions agent/php_api_internal.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "php_api_internal.h"
#include "php_call.h"
#include "php_hash.h"
#include "nr_commands_private.h"
#include "nr_datastore_instance.h"
#include "nr_header.h"
#include "nr_limits.h"
Expand Down Expand Up @@ -381,6 +382,57 @@ PHP_FUNCTION(newrelic_get_trace_json) {
nr_set_destroy(&fas_metadata.active_segments);
}

PHP_FUNCTION(newrelic_get_error_json) {
nrtxn_t* txn = NRPRG(txn);
char* json;

NR_UNUSED_HT;
NR_UNUSED_RETURN_VALUE_PTR;
NR_UNUSED_RETURN_VALUE_USED;
NR_UNUSED_THIS_PTR;

if (!nr_php_recording(TSRMLS_C)) {
RETURN_FALSE;
}

if (FAILURE == zend_parse_parameters_none()) {
RETURN_FALSE;
}

json = nr_txndata_error_to_json(txn);
if (NULL == json) {
RETURN_FALSE;
}

nr_php_zval_str(return_value, json);
nr_free(json);
}

PHP_FUNCTION(newrelic_get_transaction_guid) {
nrtxn_t* txn = NRPRG(txn);
const char* guid;

NR_UNUSED_HT;
NR_UNUSED_RETURN_VALUE_PTR;
NR_UNUSED_RETURN_VALUE_USED;
NR_UNUSED_THIS_PTR;

if (!nr_php_recording(TSRMLS_C)) {
RETURN_FALSE;
}

if (FAILURE == zend_parse_parameters_none()) {
RETURN_FALSE;
}

guid = nr_txn_get_guid(txn);
if (NULL == guid) {
RETURN_FALSE;
}

nr_php_zval_str(return_value, guid);
}

PHP_FUNCTION(newrelic_is_localhost) {
char* host = NULL;
nr_string_len_t host_len = 0;
Expand Down
16 changes: 16 additions & 0 deletions agent/php_api_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,22 @@ extern PHP_FUNCTION(newrelic_get_slowsqls);
*/
extern PHP_FUNCTION(newrelic_get_trace_json);

/*
* Proto : string newrelic_get_error_json ()
*
* Returns : The error trace JSON that would be sent to the daemon if the
* transaction ended at the point the function is called. This string
* is owned by the caller.
*/
extern PHP_FUNCTION(newrelic_get_error_json);

/*
* Proto : string newrelic_get_transaction_guid ()
*
* Returns : The transaction guid.
*/
extern PHP_FUNCTION(newrelic_get_transaction_guid);

/*
* Proto : bool newrelic_is_localhost (string $host)
*
Expand Down
75 changes: 50 additions & 25 deletions agent/php_error.c
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,9 @@ PHP_FUNCTION(newrelic_exception_handler) {
#endif /* PHP7 */
}

/* PHP Fatal errors: E_ERROR | E_USER_ERROR | E_PARSE | E_CORE_ERROR |
* E_COMPILE_ERROR | E_RECOVERABLE_ERROR */

int nr_php_error_get_priority(int type) {
switch (type) {
case E_PARSE:
Expand All @@ -299,6 +302,8 @@ int nr_php_error_get_priority(int type) {
return 50;
case E_ERROR:
return 50;
case E_RECOVERABLE_ERROR:
return 50;
case E_COMPILE_WARNING:
return 40;
case E_CORE_WARNING:
Expand All @@ -307,6 +312,12 @@ int nr_php_error_get_priority(int type) {
return 40;
case E_WARNING:
return 40;
case E_DEPRECATED:
return 30;
case E_USER_DEPRECATED:
return 30;
case E_STRICT: /* Included for backward compatibility */
return 10;
case E_USER_NOTICE:
return 0;
case E_NOTICE:
Expand Down Expand Up @@ -466,30 +477,51 @@ static char* nr_php_error_exception_message(zval* exception TSRMLS_DC) {
return message;
}

static const char* get_error_type_string(int type) {
const char* nr_php_error_get_type_string(int type) {
/* NOTE: PHP 7 makes E_STRICT irrelevant, reclassifying most of the errors as
* proper warnings, notices or E_DEPRECATED:
* https://wiki.php.net/rfc/reclassify_e_strict The E_STRICT constant will be
* retained for better compatibility, it will simply no longer have meaning in
* PHP 7. While PHP 7 was backward compatible, PHP 8 does not use E_STRICT.
*/

/* Note:
* With PHP7.4+ we should never actually be getting E_ERROR, or
* E_RECOVERABLE_ERROR here. Both are fatal errors and are handled by the
* agent's uncaught exceptions logic (unless E_RECOVERABLE_ERROR in which case
* there is no error to see)
*/
switch (type) {
case E_ERROR:
case E_ERROR: /* 1 */
return "E_ERROR";
case E_WARNING:
case E_WARNING: /* 2 */
return "E_WARNING";
case E_PARSE:
case E_PARSE: /* 4 */
return "E_PARSE";
case E_NOTICE:
case E_NOTICE: /* 8 */
return "E_NOTICE";
case E_CORE_ERROR:
case E_CORE_ERROR: /* 16 */
return "E_CORE_ERROR";
case E_CORE_WARNING:
case E_CORE_WARNING: /* 32 */
return "E_CORE_WARNING";
case E_COMPILE_ERROR:
case E_COMPILE_ERROR: /* 64 */
return "E_COMPILE_ERROR";
case E_COMPILE_WARNING:
case E_COMPILE_WARNING: /* 128 */
return "E_COMPILE_WARNING";
case E_USER_ERROR:
case E_USER_ERROR: /* 256 */
return "E_USER_ERROR";
case E_USER_WARNING:
case E_USER_WARNING: /* 512 */
return "E_USER_WARNING";
case E_USER_NOTICE:
case E_USER_NOTICE: /* 1024 */
return "E_USER_NOTICE";
case E_STRICT: /* 2048 */
return "E_STRICT";
case E_RECOVERABLE_ERROR: /* 4096 */
return "E_RECOVERABLE_ERROR";
case E_DEPRECATED: /* 8192 */
return "E_DEPRECATED";
case E_USER_DEPRECATED: /* 16348 */
return "E_USER_DEPRECATED";
default:
return "Error";
}
Expand Down Expand Up @@ -563,11 +595,6 @@ void nr_php_error_cb(int type,
const char* format,
va_list args) {
#endif /* PHP >= 8.1 */
#if ZEND_MODULE_API_NO >= ZEND_8_0_X_API_NO \
&& !defined OVERWRITE_ZEND_EXECUTE_DATA /* PHP 8.0+ and OAPI */
(void)error_filename;
(void)error_lineno;
#endif
TSRMLS_FETCH();
char* stack_json = NULL;
const char* errclass = NULL;
Expand Down Expand Up @@ -597,7 +624,7 @@ void nr_php_error_cb(int type,
#endif /* PHP < 8.0 */

stack_json = nr_php_backtrace_to_json(0 TSRMLS_CC);
errclass = get_error_type_string(type);
errclass = nr_php_error_get_type_string(type);

nr_txn_record_error(NRPRG(txn), nr_php_error_get_priority(type), true,
msg, errclass, stack_json);
Expand All @@ -622,20 +649,18 @@ void nr_php_error_cb(int type,
nr_free(msg);
nr_free(stack_json);
}
/*
* Call through to the actual error handler for PHP 7.4 and below.
* For PHP 8+ we have registered our error handler with the Observer
* API so there is no need to callback to the original.
*/
/*
* Call through to the actual error handler.
*/
#if ZEND_MODULE_API_NO < ZEND_8_0_X_API_NO
if (0 != NR_PHP_PROCESS_GLOBALS(orig_error_cb)) {
#if ZEND_MODULE_API_NO < ZEND_8_0_X_API_NO
NR_PHP_PROCESS_GLOBALS(orig_error_cb)
(type, error_filename, error_lineno, format, args);
}
#else
NR_PHP_PROCESS_GLOBALS(orig_error_cb)
(type, error_filename, error_lineno, message);
#endif /* PHP < 8.0 */
}
}

nr_status_t nr_php_error_record_exception(nrtxn_t* txn,
Expand Down
9 changes: 9 additions & 0 deletions agent/php_error.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,15 @@ extern PHP_FUNCTION(newrelic_exception_handler);
*/
extern int nr_php_error_get_priority(int type);

/*
* Purpose : Converts a PHP error type into a readable string.
*
* Params : 1. The error type.
*
* Returns : The PHP error type as constant, static string (must not be freed).
*/
extern const char* nr_php_error_get_type_string(int type);

/*
* Purpose : Install newrelic_exception_handler as the user exception handler
* in PHP.
Expand Down
2 changes: 1 addition & 1 deletion agent/php_execute.c
Original file line number Diff line number Diff line change
Expand Up @@ -387,7 +387,7 @@ static const nr_framework_table_t all_frameworks[] = {

{"Magento", "magento", NR_PSTR("app/mage.php"), 0, nr_magento1_enable,
NR_FW_MAGENTO1},
{"Magento2", "magento2", NR_PSTR("magento/framework/app/bootstrap.php"), 0,
{"Magento2", "magento2", NR_PSTR("magento/framework/registration.php"), 0,
nr_magento2_enable, NR_FW_MAGENTO2},

{"MediaWiki", "mediawiki", NR_PSTR("includes/webstart.php"), 0, nr_mediawiki_enable,
Expand Down
Loading

0 comments on commit 9caf27b

Please sign in to comment.