Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 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
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,36 @@ envoy_cc_library(
"//include/envoy/upstream:upstream_interface",
"//source/common/grpc:async_client_lib",
"//source/common/grpc:typed_async_client_lib",
"//source/common/network:utility_lib",
"//source/extensions/access_loggers/common:access_log_base",
"@envoy_api//envoy/config/accesslog/v2:als_cc",
"@envoy_api//envoy/config/filter/accesslog/v2:accesslog_cc",
"@envoy_api//envoy/service/accesslog/v2:als_cc",
],
)

envoy_cc_library(
name = "grpc_access_log_utils",
srcs = ["grpc_access_log_utils.cc"],
hdrs = ["grpc_access_log_utils.h"],
deps = [
"//include/envoy/upstream:upstream_interface",
"//source/common/network:utility_lib",
"//source/common/stream_info:stream_info_lib",
"//source/common/stream_info:utility_lib",
"@envoy_api//envoy/data/accesslog/v2:accesslog_cc",
],
)

envoy_cc_library(
name = "http_grpc_access_log_lib",
srcs = ["http_grpc_access_log_impl.cc"],
hdrs = ["http_grpc_access_log_impl.h"],
deps = [
":grpc_access_log_lib",
":grpc_access_log_utils",
],
)

envoy_cc_library(
name = "grpc_access_log_proto_descriptors_lib",
srcs = ["grpc_access_log_proto_descriptors.cc"],
Expand All @@ -44,16 +66,16 @@ envoy_cc_library(
)

envoy_cc_library(
name = "config",
srcs = ["config.cc"],
hdrs = ["config.h"],
name = "http_config",
srcs = ["http_config.cc"],
hdrs = ["http_config.h"],
deps = [
"//include/envoy/registry",
"//include/envoy/server:access_log_config_interface",
"//source/common/common:assert_lib",
"//source/common/protobuf",
"//source/extensions/access_loggers:well_known_names",
"//source/extensions/access_loggers/http_grpc:grpc_access_log_lib",
"//source/extensions/access_loggers/http_grpc:grpc_access_log_proto_descriptors_lib",
"//source/extensions/access_loggers/grpc:grpc_access_log_proto_descriptors_lib",
"//source/extensions/access_loggers/grpc:http_grpc_access_log_lib",
],
)
113 changes: 113 additions & 0 deletions source/extensions/access_loggers/grpc/grpc_access_log_impl.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
#include "extensions/access_loggers/grpc/grpc_access_log_impl.h"

#include "envoy/upstream/upstream.h"

#include "common/common/assert.h"
#include "common/network/utility.h"
#include "common/stream_info/utility.h"

namespace Envoy {
namespace Extensions {
namespace AccessLoggers {
namespace GrpcCommon {

void GrpcAccessLoggerImpl::LocalStream::onRemoteClose(Grpc::Status::GrpcStatus,
const std::string&) {
ASSERT(parent_.stream_ != absl::nullopt);
if (parent_.stream_->stream_ != nullptr) {
// Only reset if we have a stream. Otherwise we had an inline failure and we will clear the
// stream data in send().
parent_.stream_.reset();
}
}

GrpcAccessLoggerImpl::GrpcAccessLoggerImpl(Grpc::RawAsyncClientPtr&& client, std::string log_name,
std::chrono::milliseconds buffer_flush_interval_msec,
uint64_t buffer_size_bytes,
Event::Dispatcher& dispatcher,
const LocalInfo::LocalInfo& local_info)
: client_(std::move(client)), log_name_(log_name),
buffer_flush_interval_msec_(buffer_flush_interval_msec),
flush_timer_(dispatcher.createTimer([this]() {
flush();
flush_timer_->enableTimer(buffer_flush_interval_msec_);
})),
buffer_size_bytes_(buffer_size_bytes), local_info_(local_info) {
flush_timer_->enableTimer(buffer_flush_interval_msec_);
}

void GrpcAccessLoggerImpl::log(envoy::data::accesslog::v2::HTTPAccessLogEntry&& entry) {
approximate_message_size_bytes_ += entry.ByteSizeLong();
message_.mutable_http_logs()->add_log_entry()->Swap(&entry);
if (approximate_message_size_bytes_ >= buffer_size_bytes_) {
flush();
}
}

void GrpcAccessLoggerImpl::flush() {
if (!message_.has_http_logs()) {
// Nothing to flush.
return;
}

if (stream_ == absl::nullopt) {
stream_.emplace(*this);
}

if (stream_->stream_ == nullptr) {
stream_->stream_ =
client_->start(*Protobuf::DescriptorPool::generated_pool()->FindMethodByName(
"envoy.service.accesslog.v2.AccessLogService.StreamAccessLogs"),
*stream_);

auto* identifier = message_.mutable_identifier();
*identifier->mutable_node() = local_info_.node();
identifier->set_log_name(log_name_);
}

if (stream_->stream_ != nullptr) {
stream_->stream_->sendMessage(message_, false);
} else {
// Clear out the stream data due to stream creation failure.
stream_.reset();
}

// Clear the message regardless of the success.
approximate_message_size_bytes_ = 0;
message_.Clear();
}

GrpcAccessLoggerCacheImpl::GrpcAccessLoggerCacheImpl(Grpc::AsyncClientManager& async_client_manager,
Stats::Scope& scope,
ThreadLocal::SlotAllocator& tls,
const LocalInfo::LocalInfo& local_info)
: async_client_manager_(async_client_manager), scope_(scope), tls_slot_(tls.allocateSlot()),
local_info_(local_info) {
tls_slot_->set(
[](Event::Dispatcher& dispatcher) { return std::make_shared<ThreadLocalCache>(dispatcher); });
}

GrpcAccessLoggerSharedPtr GrpcAccessLoggerCacheImpl::getOrCreateLogger(
const envoy::config::accesslog::v2::CommonGrpcAccessLogConfig& config) {
// TODO(euroelessar): Consider cleaning up loggers.
auto& cache = tls_slot_->getTyped<ThreadLocalCache>();
const std::size_t cache_key = MessageUtil::hash(config);

@euroelessar euroelessar Aug 9, 2019

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With the separation in place key should include a notion if it's http or tcp logger. Otherwise Envoy can not ensure API promise anymore (that each logging stream is always either http or tcp).

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, thanks for the reminder, added a TODO here and will add the types when I implement TCP logger.

const auto it = cache.access_loggers_.find(cache_key);
if (it != cache.access_loggers_.end()) {
return it->second;
}
const Grpc::AsyncClientFactoryPtr factory =
async_client_manager_.factoryForGrpcService(config.grpc_service(), scope_, false);
const GrpcAccessLoggerSharedPtr logger = std::make_shared<GrpcAccessLoggerImpl>(
factory->create(), config.log_name(),
std::chrono::milliseconds(PROTOBUF_GET_MS_OR_DEFAULT(config, buffer_flush_interval, 1000)),
PROTOBUF_GET_WRAPPED_OR_DEFAULT(config, buffer_size_bytes, 16384), cache.dispatcher_,
local_info_);
cache.access_loggers_.emplace(cache_key, logger);
return logger;
}

} // namespace GrpcCommon
} // namespace AccessLoggers
} // namespace Extensions
} // namespace Envoy
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
namespace Envoy {
namespace Extensions {
namespace AccessLoggers {
namespace HttpGrpc {
namespace GrpcCommon {

// TODO(mattklein123): Stats

Expand Down Expand Up @@ -127,44 +127,7 @@ class GrpcAccessLoggerCacheImpl : public Singleton::Instance, public GrpcAccessL
const LocalInfo::LocalInfo& local_info_;
};

/**
* Access log Instance that streams HTTP logs over gRPC.
*/
class HttpGrpcAccessLog : public Common::ImplBase {
public:
HttpGrpcAccessLog(AccessLog::FilterPtr&& filter,
envoy::config::accesslog::v2::HttpGrpcAccessLogConfig config,
ThreadLocal::SlotAllocator& tls,
GrpcAccessLoggerCacheSharedPtr access_logger_cache);

static void responseFlagsToAccessLogResponseFlags(
envoy::data::accesslog::v2::AccessLogCommon& common_access_log,
const StreamInfo::StreamInfo& stream_info);

private:
/**
* Per-thread cached logger.
*/
struct ThreadLocalLogger : public ThreadLocal::ThreadLocalObject {
ThreadLocalLogger(GrpcAccessLoggerSharedPtr logger);

const GrpcAccessLoggerSharedPtr logger_;
};

// Common::ImplBase
void emitLog(const Http::HeaderMap& request_headers, const Http::HeaderMap& response_headers,
const Http::HeaderMap& response_trailers,
const StreamInfo::StreamInfo& stream_info) override;

const envoy::config::accesslog::v2::HttpGrpcAccessLogConfig config_;
const ThreadLocal::SlotPtr tls_slot_;
const GrpcAccessLoggerCacheSharedPtr access_logger_cache_;
std::vector<Http::LowerCaseString> request_headers_to_log_;
std::vector<Http::LowerCaseString> response_headers_to_log_;
std::vector<Http::LowerCaseString> response_trailers_to_log_;
};

} // namespace HttpGrpc
} // namespace GrpcCommon
} // namespace AccessLoggers
} // namespace Extensions
} // namespace Envoy
} // namespace Envoy
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#include "extensions/access_loggers/http_grpc/grpc_access_log_proto_descriptors.h"
#include "extensions/access_loggers/grpc/grpc_access_log_proto_descriptors.h"

#include "envoy/service/accesslog/v2/als.pb.h"

Expand Down
Loading