-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
http: dumping session state on the decode path #7390
Changes from 7 commits
d260dcd
ac93703
e0c631d
b17c382
4939235
e5c0d31
ce554b7
42e27ba
41d620a
e8bbe34
56ccb5a
510534e
9e31cd1
f0b1519
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
#pragma once | ||
|
||
#include <ostream> | ||
|
||
#include "envoy/common/pure.h" | ||
|
||
namespace Envoy { | ||
|
||
/* | ||
* A class for tracking the scope of work. | ||
* Currently this is only used for best-effort tracking the any L7 stream doing | ||
* work if a fatal error occurs. | ||
*/ | ||
class ScopeTrackedObject { | ||
public: | ||
virtual ~ScopeTrackedObject() = default; | ||
|
||
/** | ||
* Dump debug state of the object in question to the provided ostream | ||
* | ||
* This is called on Envoy fatal errors, so should do minimal memory allocation. | ||
* | ||
* @param os the ostream to output to. | ||
* @param indent_level how far to indent, for pretty-printed classes and subclasses. | ||
*/ | ||
virtual void dumpState(std::ostream& os, int indent_level = 0) const PURE; | ||
}; | ||
|
||
} // namespace Envoy |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
#pragma once | ||
|
||
#include <sstream> | ||
|
||
namespace Envoy { | ||
|
||
// A collection of macros for pretty printing objects on fatal error. | ||
// These are fairly ugly in an attempt to maximize the conditions where fatal error logging occurs, | ||
// i.e. under the Envoy signal handler if encountering a SIGSEVG due to OOM, where allocating more | ||
// memory would likely lead to the crash handler itself causing a subeqeuent OOM. | ||
|
||
#define DUMP_MEMBER(member) ", " #member ": " << (member) | ||
|
||
#define DUMP_OPTIONAL_MEMBER(member) \ | ||
", " #member ": " << ((member).has_value() ? absl::StrCat((member).value()) : "null") | ||
|
||
// Macro assumes local member variables | ||
// os (ostream) | ||
// indent_level (int) | ||
#define DUMP_DETAILS(member) \ | ||
do { \ | ||
os << spaces << #member ": "; \ | ||
if ((member) != nullptr) { \ | ||
os << "\n"; \ | ||
(member)->dumpState(os, indent_level + 1); \ | ||
} else { \ | ||
os << spaces << "null\n"; \ | ||
} \ | ||
} while (false) | ||
|
||
// Return the const char* equivalent of string(level*2, ' '), without dealing | ||
// with string creation overhead. Cap arbitrarily at 6 as we're (hopefully) | ||
// not going to have nested objects deeper than that. | ||
inline const char* spacesForLevel(int level) { | ||
mattklein123 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
switch (level) { | ||
case 0: | ||
return ""; | ||
case 1: | ||
return " "; | ||
case 2: | ||
return " "; | ||
case 3: | ||
return " "; | ||
case 4: | ||
return " "; | ||
case 5: | ||
return " "; | ||
default: | ||
return " "; | ||
} | ||
return ""; | ||
} | ||
|
||
} // namespace Envoy |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
#pragma once | ||
|
||
#include "envoy/common/scope_tracker.h" | ||
#include "envoy/event/dispatcher.h" | ||
|
||
namespace Envoy { | ||
|
||
class ScopeTrackerImpl { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: I might call this There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this name is better future-proofed for when we use the scope object for customer memory/cpu accounting (the htuch@ feature) - WDYT? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't feel strongly about it, other than to say that There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (I guess a small class comment on what it is for would be nice either way) |
||
public: | ||
ScopeTrackerImpl(const ScopeTrackedObject* object, Event::Dispatcher& dispatcher) | ||
: dispatcher_(dispatcher) { | ||
latched_object_ = dispatcher_.setTrackedObject(object); | ||
} | ||
|
||
~ScopeTrackerImpl() { dispatcher_.setTrackedObject(latched_object_); } | ||
|
||
private: | ||
const ScopeTrackedObject* latched_object_; | ||
Event::Dispatcher& dispatcher_; | ||
}; | ||
|
||
} // namespace Envoy |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -25,6 +25,10 @@ | |
|
||
#include "event2/event.h" | ||
|
||
#ifdef ENVOY_HANDLE_SIGNALS | ||
#include "exe/signal_action.h" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Reaching into exe here seems wrong from a layering perspective. Would it be better to have some other type of injected interface for this purpose? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. for layering, honestly I'd think all of the signal handling code could be moved out of exe since we use it in test, so it's somewhat core to the server handling. maybe source/server/signal/? I'm also not sure if that addresses your concerns, or if you still think there's value in the dispatcher not reaching directly to signal handling code. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. sgtm regarding moving. I might even go as far as to move some of it into source/common/signal but up to you. |
||
#endif | ||
|
||
namespace Envoy { | ||
namespace Event { | ||
|
||
|
@@ -35,11 +39,19 @@ DispatcherImpl::DispatcherImpl(Buffer::WatermarkFactoryPtr&& factory, Api::Api& | |
Event::TimeSystem& time_system) | ||
: api_(api), buffer_factory_(std::move(factory)), | ||
scheduler_(time_system.createScheduler(base_scheduler_)), | ||
deferred_delete_timer_(createTimer([this]() -> void { clearDeferredDeleteList(); })), | ||
post_timer_(createTimer([this]() -> void { runPostCallbacks(); })), | ||
current_to_delete_(&to_delete_1_) {} | ||
deferred_delete_timer_(createTimerInternal([this]() -> void { clearDeferredDeleteList(); })), | ||
post_timer_(createTimerInternal([this]() -> void { runPostCallbacks(); })), | ||
current_to_delete_(&to_delete_1_) { | ||
#ifdef ENVOY_HANDLE_SIGNALS | ||
SignalAction::registerFatalErrorHandler(*this); | ||
#endif | ||
} | ||
|
||
DispatcherImpl::~DispatcherImpl() {} | ||
DispatcherImpl::~DispatcherImpl() { | ||
#ifdef ENVOY_HANDLE_SIGNALS | ||
SignalAction::removeFatalErrorHandler(*this); | ||
#endif | ||
} | ||
|
||
void DispatcherImpl::initializeStats(Stats::Scope& scope, const std::string& prefix) { | ||
// This needs to be run in the dispatcher's thread, so that we have a thread id to log. | ||
|
@@ -133,7 +145,9 @@ Network::ListenerPtr DispatcherImpl::createUdpListener(Network::Socket& socket, | |
return Network::ListenerPtr{new Network::UdpListenerImpl(*this, socket, cb, timeSource())}; | ||
} | ||
|
||
TimerPtr DispatcherImpl::createTimer(TimerCb cb) { | ||
TimerPtr DispatcherImpl::createTimer(TimerCb cb) { return createTimerInternal(cb); } | ||
|
||
TimerPtr DispatcherImpl::createTimerInternal(TimerCb cb) { | ||
ASSERT(isThreadSafe()); | ||
return scheduler_->createTimer(cb); | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/the any/any ?