[
https://issues.apache.org/jira/browse/TS-4755?focusedWorklogId=26618&page=com.atlassian.jira.plugin.system.issuetabpanels:worklog-tabpanel#worklog-26618
]
ASF GitHub Bot logged work on TS-4755:
--------------------------------------
Author: ASF GitHub Bot
Created on: 18/Aug/16 23:52
Start Date: 18/Aug/16 23:52
Worklog Time Spent: 10m
Work Description: Github user SolidWallOfCode commented on a diff in the
pull request:
https://github.com/apache/trafficserver/pull/877#discussion_r75409533
--- Diff: plugins/experimental/header_freq/header_freq.cc ---
@@ -0,0 +1,260 @@
+/** @file
+
+ This plugin counts the number of times every header has appeared.
+ Maintains separate counts for client and origin headers.
+
+ @section license License
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+#include <iostream>
+#include <map>
+#include <sstream>
+#include <stdlib.h>
+#include <string.h>
+#include <string>
+#include <ts/ts.h>
+
+
+// plugin registration info
+static char plugin_name[] = "header_freq";
+static char vendor_name[] = "Apache Software Foundation";
+static char support_email[] = "[email protected]";
+
+// debug messages during one-time initialization
+static const char DEBUG_TAG_INIT[] = "header_freq.init";
+
+// debug messages in continuation callbacks
+static const char DEBUG_TAG_HOOK[] = "header_freq.hook";
+
+// maps from header name to # of times encountered
+static std::map<std::string, unsigned int> client_freq;
+static std::map<std::string, unsigned int> origin_freq;
+
+// for traffic_ctl, name is a convenient identifier
+static const char *ctl_tag = plugin_name;
+static const char *ctl_log = "log"; // log all data
+
+static TSMutex freq_mutex; // lock on global data
+static const int retry_time = 10; // spin after TSMutexLockTry failures
+
+static const char *log_name = plugin_name;
+static TSTextLogObject log;
+
+static bool
+freq_lock_try(TSCont contp)
+{
+ if (TSMutexLockTry(freq_mutex) != TS_SUCCESS) {
+ TSDebug(DEBUG_TAG_HOOK, "Unable to acquire lock. Retrying in %d "
+ "milliseconds", retry_time);
+ TSContSchedule(contp, retry_time, TS_THREAD_POOL_DEFAULT);
+ return false;
+ }
+ return true;
+}
+
+/**
+ * Logs the data collected, first the client, and then
+ * the origin headers.
+ */
+static void
+log_frequencies()
+{
+ std::stringstream ss("");
+
+ ss << std::endl << std::string(100, '+') << std::endl;
+
+ ss << "CLIENT HEADERS" << std::endl;
+ for (auto &elem: client_freq) {
+ ss << elem.first << ": " << elem.second << std::endl;
+ }
+
+ ss << std::endl;
+
+ ss << "ORIGIN HEADERS" << std::endl;
+ for (auto &elem: origin_freq) {
+ ss << elem.first << ": " << elem.second << std::endl;
+ }
+
+ ss << std::string(100, '+') << std::endl;
+ TSTextLogObjectWrite(log, "%s", ss.str().c_str());
+}
+
+/**
+ * Records all headers found in the buffer in the map provided. Comparison
+ * against existing entries is case-insensitive.
+ */
+static void
+count_all_headers(TSMBuffer &bufp, TSMLoc &hdr_loc, std::map<std::string,
unsigned int> &map)
+{
+ TSMLoc hdr, next_hdr;
+ hdr = TSMimeHdrFieldGet(bufp, hdr_loc, 0);
+ int n_headers = TSMimeHdrFieldsCount(bufp, hdr_loc);
+ TSDebug(DEBUG_TAG_HOOK, "%d headers found", n_headers);
+
+ // iterate through all headers
+ for (int i = 0; i < n_headers; ++i) {
+ if (hdr == NULL)
+ break;
+ next_hdr = TSMimeHdrFieldNext(bufp, hdr_loc, hdr);
+ int hdr_len;
+ const char *hdr_name = TSMimeHdrFieldNameGet(bufp, hdr_loc, hdr,
&hdr_len);
+
+ std::string str = std::string(hdr_name, hdr_len);
+
+ // make case-insensitive by converting to lowercase
+ for (auto &c: str) {
+ c = tolower(c);
+ }
+
+ // count the header
+ if (map.find(str) == map.end()) {
+ // Not found.
+ map[str] = 1;
+ } else {
+ // Found.
+ ++map[str];
+ }
+
+ TSHandleMLocRelease(bufp, hdr_loc, hdr);
+ hdr = next_hdr;
+ }
+
+ TSHandleMLocRelease(bufp, TS_NULL_MLOC, hdr_loc);
+}
+
+/**
+ * Continuation callback. Invoked to count headers on READ_REQUEST_HDR and
+ * SEND_RESPONSE_HDR hooks and to log through traffic_ctl's LIFECYCLE_MSG.
+ */
+static int
+handle_hook(TSCont contp, TSEvent event, void *edata)
+{
+ TSHttpTxn txnp;
+ TSMBuffer bufp;
+ TSMLoc hdr_loc;
+ int ret_val = 0;
+
+ // Treats the handler as a critical section because all events touch
global
+ // data
+ if (!freq_lock_try(contp)) {
--- End diff --
This is wasteful. If a continuation has a mutex then the hook and event
dispatchers will lock that mutex before invoking the continuation.
Issue Time Tracking
-------------------
Worklog Id: (was: 26618)
Time Spent: 1h (was: 50m)
> Create a plugin that would count the frequency of headers
> ---------------------------------------------------------
>
> Key: TS-4755
> URL: https://issues.apache.org/jira/browse/TS-4755
> Project: Traffic Server
> Issue Type: Improvement
> Components: Plugins
> Reporter: Bryan Call
> Assignee: Petar Penkov
> Fix For: 7.2.0
>
> Time Spent: 1h
> Remaining Estimate: 0h
>
> Create a plugin that would count the frequency of headers. Have separate
> frequency counters for origin and client.
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)