[ 
https://issues.apache.org/jira/browse/TS-4755?focusedWorklogId=26623&page=com.atlassian.jira.plugin.system.issuetabpanels:worklog-tabpanel#worklog-26623
 ]

ASF GitHub Bot logged work on TS-4755:
--------------------------------------

                Author: ASF GitHub Bot
            Created on: 19/Aug/16 01:31
            Start Date: 19/Aug/16 01:31
    Worklog Time Spent: 10m 
      Work Description: Github user petarpenkov commented on a diff in the pull 
request:

    https://github.com/apache/trafficserver/pull/877#discussion_r75416546
  
    --- 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[] = "d...@trafficserver.apache.org";
    +
    +// 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 --
    
    The way I understand your comment is "If I create a continuation with a 
non-NULL mutex, ex. TSContCreate( HANDLER, TSMutexCreate()), then the HANDLER 
becomes a critical section." Is that correct? Does that mean that in this 
scenario a lock
     is not needed and initializing the cont with a mutex will suffice?


Issue Time Tracking
-------------------

    Worklog Id:     (was: 26623)
    Time Spent: 1.5h  (was: 1h 20m)

> 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: 1.5h
>  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)

Reply via email to