You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by zw...@apache.org on 2018/05/04 00:02:55 UTC

[trafficserver] branch master updated: Add log field for error code of GOAWAY/RST_STREAM frame

This is an automated email from the ASF dual-hosted git repository.

zwoop pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficserver.git


The following commit(s) were added to refs/heads/master by this push:
     new fa03ae1  Add log field for error code of GOAWAY/RST_STREAM frame
fa03ae1 is described below

commit fa03ae1224e1cd6a275805baa628b6158eb7cef3
Author: Masaori Koshiba <ma...@apache.org>
AuthorDate: Thu Apr 26 14:32:52 2018 +0900

    Add log field for error code of GOAWAY/RST_STREAM frame
    
    Add below log fields for error code
    1). `crec`: Error code which TS received
    2). `ctec`: Error code which TS transmitted
---
 doc/admin-guide/logging/formatting.en.rst | 21 +++++++++++++++++++
 proxy/ProxyClientSession.cc               | 18 ++++++++++++++++
 proxy/ProxyClientSession.h                | 15 ++++++++++++++
 proxy/ProxyClientTransaction.cc           | 16 +++++++++++++++
 proxy/ProxyClientTransaction.h            |  2 ++
 proxy/http/HttpTransact.h                 |  3 +++
 proxy/http2/Http2ConnectionState.cc       | 12 ++++++++++-
 proxy/http2/Http2ConnectionState.h        |  2 ++
 proxy/logging/Log.cc                      | 10 +++++++++
 proxy/logging/LogAccess.cc                |  6 ++++++
 proxy/logging/LogAccess.h                 |  2 ++
 proxy/logging/LogAccessHttp.cc            | 34 +++++++++++++++++++++++++++++++
 proxy/logging/LogAccessHttp.h             |  2 ++
 13 files changed, 142 insertions(+), 1 deletion(-)

diff --git a/doc/admin-guide/logging/formatting.en.rst b/doc/admin-guide/logging/formatting.en.rst
index 56676cc..161ef7d 100644
--- a/doc/admin-guide/logging/formatting.en.rst
+++ b/doc/admin-guide/logging/formatting.en.rst
@@ -221,6 +221,27 @@ psct  Origin Server Response Content type of the document obtained by |TS| from
                              the origin server response.
 ===== ====================== ==================================================
 
+.. _admin-logging-fields-error-code:
+
+Error Code
+~~~~~~~~~~
+
+.. _crec:
+.. _ctec:
+
+The log fields of error code which is triggered session close or
+transaction close. The first byte of this field indicates that the error
+code is session level (``S``) or transaction level (``T``).
+When no error code is received or transmitted, these fileds are ``-``.
+For HTTP/2, error code are described in RFC 7540 section 7.
+
+===== ====== ==================================================================
+Field Source Description
+===== ====== ==================================================================
+crec  Client Request  Error code in hex which |TS| received
+ctec  Client Response Error code in hex which |TS| transmitted
+===== =============== =========================================================
+
 .. _admin-logging-fields-hierarchy:
 
 Hierarchical Proxies
diff --git a/proxy/ProxyClientSession.cc b/proxy/ProxyClientSession.cc
index 8cb61eb..2d7cf8d 100644
--- a/proxy/ProxyClientSession.cc
+++ b/proxy/ProxyClientSession.cc
@@ -27,6 +27,24 @@
 
 static int64_t next_cs_id = 0;
 
+size_t
+ProxyError::str(char *buf, size_t buf_len)
+{
+  size_t len = 0;
+
+  if (this->cls == ProxyErrorClass::NONE) {
+    buf[0] = '-';
+    return 1;
+  }
+
+  buf[0] = (this->cls == ProxyErrorClass::SSN) ? 'S' : 'T';
+  ++len;
+
+  len += snprintf(buf + len, buf_len - len, "%" PRIx32, this->code);
+
+  return len;
+}
+
 ProxyClientSession::ProxyClientSession() : VConnection(nullptr)
 {
   ink_zero(this->user_args);
diff --git a/proxy/ProxyClientSession.h b/proxy/ProxyClientSession.h
index efb33a4..20f1539 100644
--- a/proxy/ProxyClientSession.h
+++ b/proxy/ProxyClientSession.h
@@ -38,6 +38,21 @@
 class ProxyClientTransaction;
 struct AclRecord;
 
+enum class ProxyErrorClass {
+  NONE,
+  SSN,
+  TXN,
+};
+
+struct ProxyError {
+  ProxyError() {}
+  ProxyError(ProxyErrorClass cl, uint32_t co) : cls(cl), code(co) {}
+  size_t str(char *buf, size_t buf_len);
+
+  ProxyErrorClass cls = ProxyErrorClass::NONE;
+  uint32_t code       = 0;
+};
+
 class ProxyClientSession : public VConnection
 {
 public:
diff --git a/proxy/ProxyClientTransaction.cc b/proxy/ProxyClientTransaction.cc
index cd0c9e9..17c1c93 100644
--- a/proxy/ProxyClientTransaction.cc
+++ b/proxy/ProxyClientTransaction.cc
@@ -99,3 +99,19 @@ ProxyClientTransaction::adjust_thread(Continuation *cont, int event, void *data)
   }
   return nullptr;
 }
+
+void
+ProxyClientTransaction::set_rx_error_code(ProxyError e)
+{
+  if (this->current_reader) {
+    this->current_reader->t_state.client_info.rx_error_code = e;
+  }
+}
+
+void
+ProxyClientTransaction::set_tx_error_code(ProxyError e)
+{
+  if (this->current_reader) {
+    this->current_reader->t_state.client_info.tx_error_code = e;
+  }
+}
diff --git a/proxy/ProxyClientTransaction.h b/proxy/ProxyClientTransaction.h
index 00e4fe1..8d768dc 100644
--- a/proxy/ProxyClientTransaction.h
+++ b/proxy/ProxyClientTransaction.h
@@ -270,6 +270,8 @@ public:
   // session.
   //
   virtual int get_transaction_id() const = 0;
+  void set_rx_error_code(ProxyError e);
+  void set_tx_error_code(ProxyError e);
 
 protected:
   ProxyClientSession *parent;
diff --git a/proxy/http/HttpTransact.h b/proxy/http/HttpTransact.h
index 187531c..001ac9e 100644
--- a/proxy/http/HttpTransact.h
+++ b/proxy/http/HttpTransact.h
@@ -39,6 +39,7 @@
 #include "RemapPluginInfo.h"
 #include "UrlMapping.h"
 #include "records/I_RecHttp.h"
+#include "ProxyClientSession.h"
 
 #define MAX_DNS_LOOKUPS 2
 
@@ -584,6 +585,8 @@ public:
 
     /// @c true if the connection is transparent.
     bool is_transparent = false;
+    ProxyError rx_error_code;
+    ProxyError tx_error_code;
 
     bool
     had_connect_fail() const
diff --git a/proxy/http2/Http2ConnectionState.cc b/proxy/http2/Http2ConnectionState.cc
index a83d397..0248c53 100644
--- a/proxy/http2/Http2ConnectionState.cc
+++ b/proxy/http2/Http2ConnectionState.cc
@@ -471,6 +471,7 @@ rcv_rst_stream_frame(Http2ConnectionState &cstate, const Http2Frame &frame)
   if (stream != nullptr) {
     Http2StreamDebug(cstate.ua_session, stream_id, "RST_STREAM: Error Code: %u", rst_stream.error_code);
 
+    stream->set_rx_error_code({ProxyErrorClass::TXN, static_cast<uint32_t>(rst_stream.error_code)});
     cstate.delete_stream(stream);
   }
 
@@ -630,8 +631,8 @@ rcv_goaway_frame(Http2ConnectionState &cstate, const Http2Frame &frame)
   Http2StreamDebug(cstate.ua_session, stream_id, "GOAWAY: last stream id=%d, error code=%d", goaway.last_streamid,
                    static_cast<int>(goaway.error_code));
 
+  cstate.rx_error_code = {ProxyErrorClass::SSN, static_cast<uint32_t>(goaway.error_code)};
   cstate.handleEvent(HTTP2_SESSION_EVENT_FINI, nullptr);
-  // eventProcessor.schedule_imm(&cs, ET_NET, VC_EVENT_ERROR);
 
   return Http2Error(Http2ErrorClass::HTTP2_ERROR_CLASS_NONE);
 }
@@ -1121,6 +1122,12 @@ Http2ConnectionState::cleanup_streams()
   Http2Stream *s = stream_list.head;
   while (s) {
     Http2Stream *next = static_cast<Http2Stream *>(s->link.next);
+    if (this->rx_error_code.cls != ProxyErrorClass::NONE) {
+      s->set_rx_error_code(this->rx_error_code);
+    }
+    if (this->tx_error_code.cls != ProxyErrorClass::NONE) {
+      s->set_tx_error_code(this->tx_error_code);
+    }
     this->delete_stream(s);
     ink_assert(s != next);
     s = next;
@@ -1633,6 +1640,7 @@ Http2ConnectionState::send_rst_stream_frame(Http2StreamId id, Http2ErrorCode ec)
   // change state to closed
   Http2Stream *stream = find_stream(id);
   if (stream != nullptr) {
+    stream->set_tx_error_code({ProxyErrorClass::TXN, static_cast<uint32_t>(ec)});
     if (!stream->change_state(HTTP2_FRAME_TYPE_RST_STREAM, 0)) {
       this->send_goaway_frame(this->latest_streamid_in, Http2ErrorCode::HTTP2_ERROR_PROTOCOL_ERROR);
       this->ua_session->set_half_close_local_flag(true);
@@ -1735,6 +1743,8 @@ Http2ConnectionState::send_goaway_frame(Http2StreamId id, Http2ErrorCode ec)
   http2_write_goaway(goaway, frame.write());
   frame.finalize(HTTP2_GOAWAY_LEN);
 
+  this->tx_error_code = {ProxyErrorClass::SSN, static_cast<uint32_t>(ec)};
+
   // xmit event
   SCOPED_MUTEX_LOCK(lock, this->ua_session->mutex, this_ethread());
   this->ua_session->handleEvent(HTTP2_SESSION_EVENT_XMIT, &frame);
diff --git a/proxy/http2/Http2ConnectionState.h b/proxy/http2/Http2ConnectionState.h
index 5ee8998..916c3ff 100644
--- a/proxy/http2/Http2ConnectionState.h
+++ b/proxy/http2/Http2ConnectionState.h
@@ -114,6 +114,8 @@ class Http2ConnectionState : public Continuation
 public:
   Http2ConnectionState() : stream_list() { SET_HANDLER(&Http2ConnectionState::main_event_handler); }
 
+  ProxyError rx_error_code;
+  ProxyError tx_error_code;
   Http2ClientSession *ua_session   = nullptr;
   HpackHandle *local_hpack_handle  = nullptr;
   HpackHandle *remote_hpack_handle = nullptr;
diff --git a/proxy/logging/Log.cc b/proxy/logging/Log.cc
index 8522806..ce98bf4 100644
--- a/proxy/logging/Log.cc
+++ b/proxy/logging/Log.cc
@@ -538,6 +538,16 @@ Log::init_fields()
   global_field_list.add(field, false);
   ink_hash_table_insert(field_symbol_hash, "cruuid", field);
 
+  field = new LogField("client_rx_error_code", "crec", LogField::STRING, &LogAccess::marshal_client_rx_error_code,
+                       (LogField::UnmarshalFunc)&LogAccess::unmarshal_str);
+  global_field_list.add(field, false);
+  ink_hash_table_insert(field_symbol_hash, "crec", field);
+
+  field = new LogField("client_tx_error_code", "ctec", LogField::STRING, &LogAccess::marshal_client_tx_error_code,
+                       (LogField::UnmarshalFunc)&LogAccess::unmarshal_str);
+  global_field_list.add(field, false);
+  ink_hash_table_insert(field_symbol_hash, "ctec", field);
+
   // proxy -> client fields
   field = new LogField("proxy_resp_content_type", "psct", LogField::STRING, &LogAccess::marshal_proxy_resp_content_type,
                        (LogField::UnmarshalFunc)&LogAccess::unmarshal_str);
diff --git a/proxy/logging/LogAccess.cc b/proxy/logging/LogAccess.cc
index f903435..f484ac3 100644
--- a/proxy/logging/LogAccess.cc
+++ b/proxy/logging/LogAccess.cc
@@ -215,6 +215,12 @@ LOG_ACCESS_DEFAULT_FIELD(marshal_client_req_uuid, DEFAULT_STR_FIELD)
 /*-------------------------------------------------------------------------
   -------------------------------------------------------------------------*/
 
+LOG_ACCESS_DEFAULT_FIELD(marshal_client_rx_error_code, DEFAULT_STR_FIELD)
+LOG_ACCESS_DEFAULT_FIELD(marshal_client_tx_error_code, DEFAULT_STR_FIELD)
+
+/*-------------------------------------------------------------------------
+  -------------------------------------------------------------------------*/
+
 LOG_ACCESS_DEFAULT_FIELD(marshal_client_req_timestamp_sec, DEFAULT_INT_FIELD)
 LOG_ACCESS_DEFAULT_FIELD(marshal_client_req_timestamp_ms, DEFAULT_INT_FIELD)
 
diff --git a/proxy/logging/LogAccess.h b/proxy/logging/LogAccess.h
index 414fb57..6f86882 100644
--- a/proxy/logging/LogAccess.h
+++ b/proxy/logging/LogAccess.h
@@ -196,6 +196,8 @@ public:
   inkcoreapi virtual int marshal_client_finish_status_code(char *);     // INT
   inkcoreapi virtual int marshal_client_req_id(char *);                 // INT
   inkcoreapi virtual int marshal_client_req_uuid(char *);               // STR
+  inkcoreapi virtual int marshal_client_rx_error_code(char *);          // STR
+  inkcoreapi virtual int marshal_client_tx_error_code(char *);          // STR
 
   //
   // proxy -> client fields
diff --git a/proxy/logging/LogAccessHttp.cc b/proxy/logging/LogAccessHttp.cc
index f829720..889ab1d 100644
--- a/proxy/logging/LogAccessHttp.cc
+++ b/proxy/logging/LogAccessHttp.cc
@@ -800,6 +800,40 @@ LogAccessHttp::marshal_client_req_uuid(char *buf)
 }
 
 /*-------------------------------------------------------------------------
+  -------------------------------------------------------------------------*/
+
+// 1 ('S'/'T' flag) + 8 (Error Code) + 1 ('\0')
+static constexpr size_t MAX_PROXY_ERROR_CODE_SIZE = 10;
+
+int
+LogAccessHttp::marshal_client_rx_error_code(char *buf)
+{
+  char error_code[MAX_PROXY_ERROR_CODE_SIZE] = {0};
+  m_http_sm->t_state.client_info.rx_error_code.str(error_code, sizeof(error_code));
+  int round_len = LogAccess::strlen(error_code);
+
+  if (buf) {
+    marshal_str(buf, error_code, round_len);
+  }
+
+  return round_len;
+}
+
+int
+LogAccessHttp::marshal_client_tx_error_code(char *buf)
+{
+  char error_code[MAX_PROXY_ERROR_CODE_SIZE] = {0};
+  m_http_sm->t_state.client_info.tx_error_code.str(error_code, sizeof(error_code));
+  int round_len = LogAccess::strlen(error_code);
+
+  if (buf) {
+    marshal_str(buf, error_code, round_len);
+  }
+
+  return round_len;
+}
+
+/*-------------------------------------------------------------------------
 -------------------------------------------------------------------------*/
 int
 LogAccessHttp::marshal_client_security_protocol(char *buf)
diff --git a/proxy/logging/LogAccessHttp.h b/proxy/logging/LogAccessHttp.h
index c10f260..8ba4824 100644
--- a/proxy/logging/LogAccessHttp.h
+++ b/proxy/logging/LogAccessHttp.h
@@ -82,6 +82,8 @@ public:
   int marshal_client_finish_status_code(char *) override;     // INT
   int marshal_client_req_id(char *) override;                 // INT
   int marshal_client_req_uuid(char *) override;               // STR
+  int marshal_client_rx_error_code(char *) override;          // STR
+  int marshal_client_tx_error_code(char *) override;          // STR
 
   //
   // proxy -> client fields

-- 
To stop receiving notification emails like this one, please contact
zwoop@apache.org.