forked from elastic/apm-agent-php
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Debug option to collect diagnostic information from PHP worker process (
- Loading branch information
Showing
20 changed files
with
422 additions
and
20 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
|
||
#include "Diagnostics.h" | ||
|
||
#include <sys/types.h> | ||
#include <unistd.h> | ||
|
||
#include <chrono> | ||
#include <fstream> | ||
#include <sstream> | ||
#include <iomanip> | ||
|
||
namespace elasticapm::utils { | ||
|
||
namespace detail { | ||
static constexpr int separatorWidth = 60; | ||
static constexpr char separator = '='; | ||
} | ||
|
||
static void getProcessDiags(std::ostream &out, std::string_view name) { | ||
out << std::setfill(detail::separator) << std::setw(detail::separatorWidth) << detail::separator << std::endl; | ||
out << "Process " << name << ":" << std::endl; | ||
out << std::setfill(detail::separator) << std::setw(detail::separatorWidth) << detail::separator << std::endl; | ||
try { | ||
std::stringstream mapsname; | ||
mapsname << "/proc/self/" << name; | ||
std::ifstream maps; | ||
maps.exceptions(std::ios_base::failbit); | ||
maps.open(mapsname.str()); | ||
out << maps.rdbuf(); | ||
maps.close(); | ||
} catch (std::exception const &e) { | ||
out << "Unable to get process " << name << ": " << e.what() << std::endl; | ||
} | ||
} | ||
|
||
static void getDiagnosticInformation(std::ostream &out, elasticapm::php::PhpBridgeInterface const &bridge) { | ||
out << std::setfill(detail::separator) << std::setw(detail::separatorWidth) << detail::separator << std::endl; | ||
out << "Elastic APM PHP agent diagnostics:" << std::endl; | ||
out << std::setfill(detail::separator) << std::setw(detail::separatorWidth) << detail::separator << std::endl; | ||
std::time_t time = std::time({}); | ||
char timeString[std::size("yyyy-mm-ddThh:mm:ssZ")]; | ||
std::strftime(std::data(timeString), std::size(timeString), "%FT%TZ", std::gmtime(&time)); | ||
|
||
out << "Time: " << timeString << " UTC (" << std::chrono::milliseconds(time).count() << ')' << std::endl; | ||
out << "PID: " << getpid() << std::endl; | ||
out << "PPID: " << getppid() << std::endl; | ||
out << "UID: " << getuid() << std::endl; | ||
|
||
auto extensions = bridge.getExtensionList(); | ||
if (extensions.size() > 0) { | ||
out << std::setfill(detail::separator) << std::setw(detail::separatorWidth) << detail::separator << std::endl; | ||
out << "Loaded extensions:" << std::endl; | ||
out << std::setfill(detail::separator) << std::setw(detail::separatorWidth) << detail::separator << std::endl; | ||
|
||
for (auto const &extension : extensions) { | ||
out << extension.name << " " << extension.version << std::endl; | ||
} | ||
} | ||
|
||
out << std::setfill(detail::separator) << std::setw(detail::separatorWidth) << detail::separator << std::endl << std::endl; | ||
out << "phpinfo() output:" << std::endl; | ||
out << std::setfill(detail::separator) << std::setw(detail::separatorWidth) << detail::separator << std::endl; | ||
out << bridge.getPhpInfo() << std::endl; | ||
|
||
getProcessDiags(out, "maps"); | ||
getProcessDiags(out, "smaps_rollup"); | ||
getProcessDiags(out, "status"); | ||
getProcessDiags(out, "limits"); | ||
getProcessDiags(out, "cgroup"); | ||
getProcessDiags(out, "cmdline"); | ||
getProcessDiags(out, "mountinfo"); | ||
getProcessDiags(out, "mounts"); | ||
getProcessDiags(out, "mountstats"); | ||
getProcessDiags(out, "stat"); | ||
} | ||
|
||
void storeDiagnosticInformation(std::string_view outputFileName, elasticapm::php::PhpBridgeInterface const &bridge) { | ||
std::ofstream out; | ||
out.exceptions(std::ios_base::failbit); | ||
out.open(outputFileName.data()); | ||
getDiagnosticInformation(out, bridge); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
|
||
#pragma once | ||
|
||
#include "PhpBridgeInterface.h" | ||
|
||
namespace elasticapm::utils { | ||
|
||
void storeDiagnosticInformation(std::string_view outputFileName, elasticapm::php::PhpBridgeInterface const &bridge); //throws | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,15 +1,27 @@ | ||
#pragma once | ||
|
||
#include <chrono> | ||
#include <string> | ||
#include <vector> | ||
|
||
namespace elasticapm::php { | ||
|
||
|
||
class PhpBridgeInterface { | ||
public: | ||
|
||
struct phpExtensionInfo_t { | ||
std::string name; | ||
std::string version; | ||
}; | ||
|
||
virtual ~PhpBridgeInterface() = default; | ||
|
||
virtual bool callInferredSpans(std::chrono::milliseconds duration) = 0; | ||
virtual bool callInferredSpans(std::chrono::milliseconds duration) const = 0; | ||
virtual std::vector<phpExtensionInfo_t> getExtensionList() const = 0; | ||
virtual std::string getPhpInfo() const = 0; | ||
|
||
|
||
}; | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
|
||
|
||
#include <boost/interprocess/anonymous_shared_memory.hpp> | ||
#include <boost/interprocess/mapped_region.hpp> | ||
#include <boost/interprocess/sync/interprocess_upgradable_mutex.hpp> | ||
#include <boost/interprocess/sync/scoped_lock.hpp> | ||
#include <boost/interprocess/sync/sharable_lock.hpp> | ||
|
||
namespace elasticapm::php { | ||
|
||
class SharedMemoryState { | ||
public: | ||
struct SharedData { | ||
boost::interprocess::interprocess_upgradable_mutex mutex; | ||
bool oneTimeTaskAmongWorkersExecuted = false; | ||
}; | ||
|
||
bool shouldExecuteOneTimeTaskAmongWorkers() { | ||
{ | ||
boost::interprocess::sharable_lock< decltype( SharedData::mutex ) > lock( data_->mutex ); | ||
if ( data_->oneTimeTaskAmongWorkersExecuted ) | ||
{ | ||
return false; | ||
} | ||
} | ||
|
||
boost::interprocess::scoped_lock< decltype( SharedData::mutex ) > ulock( data_->mutex ); | ||
if ( data_->oneTimeTaskAmongWorkersExecuted ) | ||
{ | ||
return false; | ||
} | ||
data_->oneTimeTaskAmongWorkersExecuted = true; | ||
return true; | ||
} | ||
|
||
|
||
protected: | ||
boost::interprocess::mapped_region region_{ boost::interprocess::anonymous_shared_memory( sizeof( SharedData ) ) }; | ||
SharedData* data_{ new (region_.get_address()) SharedData }; | ||
}; | ||
|
||
} |
Oops, something went wrong.