• Main Page
  • Related Pages
  • Namespaces
  • Data Structures
  • Files
  • File List
  • Globals

LogAccess.cc

Go to the documentation of this file.
00001 /** @file
00002 
00003   This file implements the LogAccess class.
00004 
00005   @section license License
00006 
00007   Licensed to the Apache Software Foundation (ASF) under one
00008   or more contributor license agreements.  See the NOTICE file
00009   distributed with this work for additional information
00010   regarding copyright ownership.  The ASF licenses this file
00011   to you under the Apache License, Version 2.0 (the
00012   "License"); you may not use this file except in compliance
00013   with the License.  You may obtain a copy of the License at
00014 
00015       http://www.apache.org/licenses/LICENSE-2.0
00016 
00017   Unless required by applicable law or agreed to in writing, software
00018   distributed under the License is distributed on an "AS IS" BASIS,
00019   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00020   See the License for the specific language governing permissions and
00021   limitations under the License.
00022 
00023   @section description
00024   This file implements the LogAccess class.  However, LogAccess is an
00025   abstract base class, providing an interface that logging uses to get
00026   information from a module, such as HTTP or ICP.  Each module derives a
00027   specific implementation from this base class (such as LogAccessHttp), and
00028   implements the virtual accessor functions there.
00029 
00030   The LogAccess class also defines a set of static functions that are used
00031   to provide support for marshalling and unmarshalling support for the other
00032   LogAccess derived classes.
00033  */
00034 #include "libts.h"
00035 
00036 #include "Error.h"
00037 #include "HTTP.h"
00038 
00039 #include "P_Net.h"
00040 #include "P_Cache.h"
00041 #include "I_Machine.h"
00042 #include "LogAccess.h"
00043 #include "LogField.h"
00044 #include "LogFilter.h"
00045 #include "LogUtils.h"
00046 #include "LogFormat.h"
00047 #include "LogObject.h"
00048 #include "LogConfig.h"
00049 #include "LogBuffer.h"
00050 #include "Log.h"
00051 
00052 
00053 /*-------------------------------------------------------------------------
00054   LogAccess::init
00055   -------------------------------------------------------------------------*/
00056 
00057 void
00058 LogAccess::init()
00059 {
00060   if (initialized) {
00061     return;
00062   }
00063   //
00064   // Here is where we would perform any initialization code.
00065   //
00066 
00067   initialized = true;
00068 }
00069 
00070 /*-------------------------------------------------------------------------
00071   The following functions provide a default implementation for the base
00072   class marshalling routines so that each subsequent LogAccess* class only
00073   has to implement those functions that are to override this default
00074   implementation.
00075   -------------------------------------------------------------------------*/
00076 
00077 int
00078 LogAccess::marshal_plugin_identity_id(char *buf)
00079 {
00080   DEFAULT_INT_FIELD;
00081 }
00082 
00083 int
00084 LogAccess::marshal_plugin_identity_tag(char *buf)
00085 {
00086   DEFAULT_STR_FIELD;
00087 }
00088 
00089 int
00090 LogAccess::marshal_client_host_ip(char *buf)
00091 {
00092   DEFAULT_IP_FIELD;
00093 }
00094 
00095 /*-------------------------------------------------------------------------
00096   -------------------------------------------------------------------------*/
00097 
00098 int
00099 LogAccess::marshal_client_host_port(char *buf)
00100 {
00101   DEFAULT_INT_FIELD;
00102 }
00103 
00104 /*-------------------------------------------------------------------------
00105   -------------------------------------------------------------------------*/
00106 
00107 int
00108 LogAccess::marshal_client_auth_user_name(char *buf)
00109 {
00110   DEFAULT_STR_FIELD;
00111 }
00112 
00113 /*-------------------------------------------------------------------------
00114   -------------------------------------------------------------------------*/
00115 
00116 int
00117 LogAccess::marshal_client_req_text(char *buf)
00118 {
00119   DEFAULT_STR_FIELD;
00120 }
00121 
00122 /*-------------------------------------------------------------------------
00123   -------------------------------------------------------------------------*/
00124 
00125 int
00126 LogAccess::marshal_client_req_http_method(char *buf)
00127 {
00128   DEFAULT_STR_FIELD;
00129 }
00130 
00131 /*-------------------------------------------------------------------------
00132   -------------------------------------------------------------------------*/
00133 
00134 int
00135 LogAccess::marshal_client_req_url(char *buf)
00136 {
00137   DEFAULT_STR_FIELD;
00138 }
00139 
00140 /*-------------------------------------------------------------------------
00141   -------------------------------------------------------------------------*/
00142 
00143 int
00144 LogAccess::marshal_client_req_url_canon(char *buf)
00145 {
00146   DEFAULT_STR_FIELD;
00147 }
00148 
00149 /*-------------------------------------------------------------------------
00150   -------------------------------------------------------------------------*/
00151 
00152 int
00153 LogAccess::marshal_client_req_unmapped_url_canon(char *buf)
00154 {
00155   DEFAULT_STR_FIELD;
00156 }
00157 
00158 /*-------------------------------------------------------------------------
00159   -------------------------------------------------------------------------*/
00160 
00161 int
00162 LogAccess::marshal_client_req_unmapped_url_path(char *buf)
00163 {
00164   DEFAULT_STR_FIELD;
00165 }
00166 
00167 /*-------------------------------------------------------------------------
00168   -------------------------------------------------------------------------*/
00169 
00170 int
00171 LogAccess::marshal_client_req_unmapped_url_host(char *buf)
00172 {
00173   DEFAULT_STR_FIELD;
00174 }
00175 
00176 /*-------------------------------------------------------------------------
00177   -------------------------------------------------------------------------*/
00178 
00179 int
00180 LogAccess::marshal_client_req_url_path(char *buf)
00181 {
00182   DEFAULT_STR_FIELD;
00183 }
00184 
00185 /*-------------------------------------------------------------------------
00186   -------------------------------------------------------------------------*/
00187 
00188 int
00189 LogAccess::marshal_client_req_url_scheme(char *buf)
00190 {
00191   DEFAULT_STR_FIELD;
00192 }
00193 
00194 /*-------------------------------------------------------------------------
00195   This case is special because it really stores 2 ints.
00196   -------------------------------------------------------------------------*/
00197 
00198 int
00199 LogAccess::marshal_client_req_http_version(char *buf)
00200 {
00201   if (buf) {
00202     int64_t major = 0;
00203     int64_t minor = 0;
00204     marshal_int(buf, major);
00205     marshal_int((buf + INK_MIN_ALIGN), minor);
00206   }
00207   return (2 * INK_MIN_ALIGN);
00208 }
00209 
00210 /*-------------------------------------------------------------------------
00211   -------------------------------------------------------------------------*/
00212 
00213 int
00214 LogAccess::marshal_client_req_header_len(char *buf)
00215 {
00216   DEFAULT_INT_FIELD;
00217 }
00218 
00219 /*-------------------------------------------------------------------------
00220   -------------------------------------------------------------------------*/
00221 
00222 int
00223 LogAccess::marshal_client_req_body_len(char *buf)
00224 {
00225   DEFAULT_INT_FIELD;
00226 }
00227 
00228 /*-------------------------------------------------------------------------
00229   -------------------------------------------------------------------------*/
00230 
00231 int
00232 LogAccess::marshal_client_finish_status_code(char *buf)
00233 {
00234   DEFAULT_INT_FIELD;
00235 }
00236 
00237 /*-------------------------------------------------------------------------
00238   -------------------------------------------------------------------------*/
00239 
00240 int
00241 LogAccess::marshal_proxy_resp_content_type(char *buf)
00242 {
00243   DEFAULT_STR_FIELD;
00244 }
00245 
00246 /*-------------------------------------------------------------------------
00247   -------------------------------------------------------------------------*/
00248 
00249 int
00250 LogAccess::marshal_proxy_resp_squid_len(char *buf)
00251 {
00252   DEFAULT_INT_FIELD;
00253 }
00254 
00255 /*-------------------------------------------------------------------------
00256   -------------------------------------------------------------------------*/
00257 
00258 int
00259 LogAccess::marshal_proxy_resp_content_len(char *buf)
00260 {
00261   DEFAULT_INT_FIELD;
00262 }
00263 
00264 /*-------------------------------------------------------------------------
00265   -------------------------------------------------------------------------*/
00266 
00267 int
00268 LogAccess::marshal_proxy_resp_status_code(char *buf)
00269 {
00270   DEFAULT_INT_FIELD;
00271 }
00272 
00273 /*-------------------------------------------------------------------------
00274   -------------------------------------------------------------------------*/
00275 
00276 int
00277 LogAccess::marshal_proxy_resp_header_len(char *buf)
00278 {
00279   DEFAULT_INT_FIELD;
00280 }
00281 
00282 /*-------------------------------------------------------------------------
00283   -------------------------------------------------------------------------*/
00284 
00285 int
00286 LogAccess::marshal_proxy_finish_status_code(char *buf)
00287 {
00288   DEFAULT_INT_FIELD;
00289 }
00290 
00291 /*-------------------------------------------------------------------------
00292   -------------------------------------------------------------------------*/
00293 
00294 int
00295 LogAccess::marshal_cache_result_code(char *buf)
00296 {
00297   DEFAULT_INT_FIELD;
00298 }
00299 
00300 /*-------------------------------------------------------------------------
00301   -------------------------------------------------------------------------*/
00302 
00303 int
00304 LogAccess::marshal_proxy_req_header_len(char *buf)
00305 {
00306   DEFAULT_INT_FIELD;
00307 }
00308 
00309 /*-------------------------------------------------------------------------
00310   -------------------------------------------------------------------------*/
00311 
00312 int
00313 LogAccess::marshal_proxy_req_body_len(char *buf)
00314 {
00315   DEFAULT_INT_FIELD;
00316 }
00317 
00318 /*-------------------------------------------------------------------------
00319   -------------------------------------------------------------------------*/
00320 
00321 int
00322 LogAccess::marshal_proxy_req_server_name(char *buf)
00323 {
00324   DEFAULT_STR_FIELD;
00325 }
00326 
00327 /*-------------------------------------------------------------------------
00328   -------------------------------------------------------------------------*/
00329 
00330 int
00331 LogAccess::marshal_proxy_req_server_ip(char *buf)
00332 {
00333   DEFAULT_IP_FIELD;
00334 }
00335 
00336 /*-------------------------------------------------------------------------
00337   -------------------------------------------------------------------------*/
00338 
00339 int
00340 LogAccess::marshal_proxy_hierarchy_route(char *buf)
00341 {
00342   DEFAULT_INT_FIELD;
00343 }
00344 
00345 #ifndef INK_NO_CONGESTION_CONTROL
00346 /*-------------------------------------------------------------------------
00347   -------------------------------------------------------------------------*/
00348 
00349 int
00350 LogAccess::marshal_client_retry_after_time(char *buf)
00351 {
00352   DEFAULT_INT_FIELD;
00353 }
00354 #endif
00355 
00356 /*-------------------------------------------------------------------------
00357   -------------------------------------------------------------------------*/
00358 
00359 int
00360 LogAccess::marshal_proxy_host_name(char *buf)
00361 {
00362   char *str = NULL;
00363   int len = 0;
00364   Machine *machine = Machine::instance();
00365 
00366   if (machine) {
00367     str = machine->hostname;
00368   }
00369 
00370   len = LogAccess::strlen(str);
00371 
00372   if (buf) {
00373     marshal_str(buf, str, len);
00374   }
00375 
00376   return len;
00377 }
00378 
00379 /*-------------------------------------------------------------------------
00380   -------------------------------------------------------------------------*/
00381 
00382 int
00383 LogAccess::marshal_proxy_host_ip(char *buf)
00384 {
00385   return marshal_ip(buf, &Machine::instance()->ip.sa);
00386 }
00387 
00388 
00389 /*-------------------------------------------------------------------------
00390   -------------------------------------------------------------------------*/
00391 
00392 int
00393 LogAccess::marshal_server_host_ip(char *buf)
00394 {
00395   DEFAULT_IP_FIELD;
00396 }
00397 
00398 /*-------------------------------------------------------------------------
00399   -------------------------------------------------------------------------*/
00400 
00401 int
00402 LogAccess::marshal_server_host_name(char *buf)
00403 {
00404   DEFAULT_STR_FIELD;
00405 }
00406 
00407 /*-------------------------------------------------------------------------
00408   -------------------------------------------------------------------------*/
00409 
00410 int
00411 LogAccess::marshal_server_resp_status_code(char *buf)
00412 {
00413   DEFAULT_INT_FIELD;
00414 }
00415 
00416 /*-------------------------------------------------------------------------
00417   -------------------------------------------------------------------------*/
00418 
00419 int
00420 LogAccess::marshal_server_resp_content_len(char *buf)
00421 {
00422   DEFAULT_INT_FIELD;
00423 }
00424 
00425 /*-------------------------------------------------------------------------
00426   -------------------------------------------------------------------------*/
00427 
00428 int
00429 LogAccess::marshal_server_resp_header_len(char *buf)
00430 {
00431   DEFAULT_INT_FIELD;
00432 }
00433 
00434 /*-------------------------------------------------------------------------
00435   This case is special because it really stores 2 ints.
00436   -------------------------------------------------------------------------*/
00437 
00438 int
00439 LogAccess::marshal_server_resp_http_version(char *buf)
00440 {
00441   if (buf) {
00442     int64_t major = 0;
00443     int64_t minor = 0;
00444     marshal_int(buf, major);
00445     marshal_int((buf + INK_MIN_ALIGN), minor);
00446   }
00447   return (2 * INK_MIN_ALIGN);
00448 }
00449 
00450 /*-------------------------------------------------------------------------
00451   -------------------------------------------------------------------------*/
00452 
00453 int
00454 LogAccess::marshal_cache_resp_status_code(char *buf)
00455 {
00456   DEFAULT_INT_FIELD;
00457 }
00458 
00459 /*-------------------------------------------------------------------------
00460   -------------------------------------------------------------------------*/
00461 
00462 int
00463 LogAccess::marshal_cache_resp_content_len(char *buf)
00464 {
00465   DEFAULT_INT_FIELD;
00466 }
00467 
00468 /*-------------------------------------------------------------------------
00469   -------------------------------------------------------------------------*/
00470 
00471 int
00472 LogAccess::marshal_cache_resp_header_len(char *buf)
00473 {
00474   DEFAULT_INT_FIELD;
00475 }
00476 
00477 /*-------------------------------------------------------------------------
00478   This case is special because it really stores 2 ints.
00479   -------------------------------------------------------------------------*/
00480 
00481 int
00482 LogAccess::marshal_cache_resp_http_version(char *buf)
00483 {
00484   if (buf) {
00485     int64_t major = 0;
00486     int64_t minor = 0;
00487     marshal_int(buf, major);
00488     marshal_int((buf + INK_MIN_ALIGN), minor);
00489   }
00490   return (2 * INK_MIN_ALIGN);
00491 }
00492 
00493 int
00494 LogAccess::marshal_cache_write_code(char *buf)
00495 {
00496   DEFAULT_INT_FIELD;
00497 }
00498 
00499 int
00500 LogAccess::marshal_cache_write_transform_code(char *buf)
00501 {
00502   DEFAULT_INT_FIELD;
00503 }
00504 
00505 /*-------------------------------------------------------------------------
00506   -------------------------------------------------------------------------*/
00507 
00508 int
00509 LogAccess::marshal_transfer_time_ms(char *buf)
00510 {
00511   DEFAULT_INT_FIELD;
00512 }
00513 
00514 int
00515 LogAccess::marshal_transfer_time_s(char *buf)
00516 {
00517   DEFAULT_INT_FIELD;
00518 }
00519 
00520 /*-------------------------------------------------------------------------
00521   -------------------------------------------------------------------------*/
00522 
00523 int
00524 LogAccess::marshal_file_size(char *buf)
00525 {
00526   DEFAULT_INT_FIELD;
00527 }
00528 
00529 /*-------------------------------------------------------------------------
00530   -------------------------------------------------------------------------*/
00531 int
00532 LogAccess::marshal_http_header_field(LogField::Container /* container ATS_UNUSED */,
00533                                      char * /* field ATS_UNUSED */, char *buf)
00534 {
00535   DEFAULT_STR_FIELD;
00536 }
00537 
00538 
00539 /*-------------------------------------------------------------------------
00540 
00541   -------------------------------------------------------------------------*/
00542 int
00543 LogAccess::marshal_http_header_field_escapify(LogField::Container /* container ATS_UNUSED */,
00544                                               char * /* field ATS_UNUSED */, char *buf)
00545 {
00546   DEFAULT_STR_FIELD;
00547 }
00548 
00549 /*-------------------------------------------------------------------------
00550 
00551   The following functions have a non-virtual base-class implementation.
00552   -------------------------------------------------------------------------*/
00553 
00554 /*-------------------------------------------------------------------------
00555   LogAccess::marshal_client_req_timestamp_sec
00556 
00557   This does nothing because the timestamp is already in the LogEntryHeader.
00558   -------------------------------------------------------------------------*/
00559 
00560 int
00561 LogAccess::marshal_client_req_timestamp_sec(char *buf)
00562 {
00563   // in the case of aggregate fields, we need the space, so we'll always
00564   // reserve it.  For a non-aggregate timestamp, this space is not used.
00565   DEFAULT_INT_FIELD;
00566 }
00567 
00568 /*-------------------------------------------------------------------------
00569   -------------------------------------------------------------------------*/
00570 
00571 int
00572 LogAccess::marshal_entry_type(char *buf)
00573 {
00574   if (buf) {
00575     int64_t val = (int64_t) entry_type();
00576     marshal_int(buf, val);
00577   }
00578   return INK_MIN_ALIGN;
00579 }
00580 
00581 /*-------------------------------------------------------------------------
00582   -------------------------------------------------------------------------*/
00583 
00584 int
00585 LogAccess::marshal_config_int_var(char *config_var, char *buf)
00586 {
00587   if (buf) {
00588     int64_t val = (int64_t) REC_ConfigReadInteger(config_var);
00589     marshal_int(buf, val);
00590   }
00591   return INK_MIN_ALIGN;
00592 }
00593 
00594 /*-------------------------------------------------------------------------
00595   -------------------------------------------------------------------------*/
00596 
00597 int
00598 LogAccess::marshal_config_str_var(char *config_var, char *buf)
00599 {
00600   char *str = NULL;
00601   str = REC_ConfigReadString(config_var);
00602   int len = LogAccess::strlen(str);
00603   if (buf) {
00604     marshal_str(buf, str, len);
00605   }
00606   ats_free(str);
00607   return len;
00608 }
00609 
00610 // To allow for a generic marshal_record function, rather than
00611 // multiple functions (one per data type) we always marshal a record
00612 // as a string of a fixed length.  We use a fixed length because the
00613 // marshal_record function can be called with a null *buf to request
00614 // the length of the record, and later with a non-null *buf to
00615 // actually request the record to be inserted in the buffer, and both
00616 // calls should return the same number of characters. If we did not
00617 // enforce a fixed size, this would not necesarilly be the case
00618 // because records --statistics in particular-- can potentially change
00619 // between one call and the other.
00620 //
00621 int
00622 LogAccess::marshal_record(char *record, char *buf)
00623 {
00624   const unsigned int max_chars = MARSHAL_RECORD_LENGTH;
00625 
00626   if (NULL == buf) {
00627     return max_chars;
00628   }
00629 
00630   const char *record_not_found_msg = "RECORD_NOT_FOUND";
00631   const unsigned int record_not_found_chars = ::strlen(record_not_found_msg) + 1;
00632 
00633   char ascii_buf[max_chars];
00634   const char *out_buf;
00635   unsigned int num_chars;
00636 
00637 #define LOG_INTEGER RECD_INT
00638 #define LOG_COUNTER RECD_COUNTER
00639 #define LOG_FLOAT   RECD_FLOAT
00640 #define LOG_STRING  RECD_STRING
00641 
00642   RecDataT stype = RECD_NULL;
00643   bool found = false;
00644 
00645   if (RecGetRecordDataType(record, &stype) != REC_ERR_OKAY) {
00646     out_buf = "INVALID_RECORD";
00647     num_chars = ::strlen(out_buf) + 1;
00648   } else {
00649     if (LOG_INTEGER == stype || LOG_COUNTER == stype) {
00650       // we assume MgmtInt and MgmtIntCounter are int64_t for the
00651       // conversion below, if this ever changes we should modify
00652       // accordingly
00653       //
00654       ink_assert(sizeof(int64_t) >= sizeof(RecInt) && sizeof(int64_t) >= sizeof(RecCounter));
00655 
00656       // so that a 64 bit integer will fit (including sign and eos)
00657       //
00658       ink_assert(max_chars > 21);
00659 
00660       int64_t val = (int64_t) (LOG_INTEGER == stype ? REC_readInteger(record, &found) : REC_readCounter(record, &found));
00661 
00662       if (found) {
00663 
00664         out_buf = int64_to_str(ascii_buf, max_chars, val, &num_chars);
00665         ink_assert(out_buf);
00666       } else {
00667         out_buf = (char *) record_not_found_msg;
00668         num_chars = record_not_found_chars;
00669       }
00670     } else if (LOG_FLOAT == stype) {
00671       // we assume MgmtFloat is at least a float for the conversion below
00672       // (the conversion itself assumes a double because of the %e)
00673       // if this ever changes we should modify accordingly
00674       //
00675       ink_assert(sizeof(double) >= sizeof(RecFloat));
00676 
00677       RecFloat val = REC_readFloat(record, &found);
00678 
00679       if (found) {
00680         // snprintf does not support "%e" in the format
00681         // and we want to use "%e" because it is the most concise
00682         // notation
00683 
00684         num_chars = snprintf(ascii_buf, sizeof(ascii_buf), "%e", val) + 1;      // include eos
00685 
00686         // the "%e" field above should take 13 characters at most
00687         //
00688         ink_assert(num_chars <= max_chars);
00689 
00690         // the following should never be true
00691         //
00692         if (num_chars > max_chars) {
00693           // data does not fit, output asterisks
00694           out_buf = "***";
00695           num_chars = ::strlen(out_buf) + 1;
00696         } else {
00697           out_buf = ascii_buf;
00698         }
00699       } else {
00700         out_buf = (char *) record_not_found_msg;
00701         num_chars = record_not_found_chars;
00702       }
00703     } else if (LOG_STRING == stype) {
00704       out_buf = REC_readString(record, &found);
00705 
00706       if (found) {
00707         if (out_buf != 0 && out_buf[0] != 0) {
00708           num_chars =::strlen(out_buf) + 1;
00709           if (num_chars > max_chars) {
00710             // truncate string and write ellipsis at the end
00711             memcpy(ascii_buf, out_buf, max_chars - 4);
00712             ascii_buf[max_chars - 1] = 0;
00713             ascii_buf[max_chars - 2] = '.';
00714             ascii_buf[max_chars - 3] = '.';
00715             ascii_buf[max_chars - 4] = '.';
00716             out_buf = ascii_buf;
00717             num_chars = max_chars;
00718           }
00719         } else {
00720           out_buf = "NULL";
00721           num_chars = ::strlen(out_buf) + 1;
00722         }
00723       } else {
00724         out_buf = (char *) record_not_found_msg;
00725         num_chars = record_not_found_chars;
00726       }
00727     } else {
00728       out_buf = "INVALID_MgmtType";
00729       num_chars = ::strlen(out_buf) + 1;
00730       ink_assert(!"invalid MgmtType for requested record");
00731     }
00732   }
00733 
00734   ink_assert(num_chars <= max_chars);
00735   memcpy(buf, out_buf, num_chars);
00736 
00737 
00738   return max_chars;
00739 }
00740 
00741 
00742 /*-------------------------------------------------------------------------
00743   LogAccess::marshal_str
00744 
00745   Copy the given string to the destination buffer, including the trailing
00746   NULL.  For binary formatting, we need the NULL to distinguish the end of
00747   the string, and we'll remove it for ascii formatting.
00748   ASSUMES dest IS NOT NULL.
00749   The array pointed to by dest must be at least padded_len in length.
00750   -------------------------------------------------------------------------*/
00751 
00752 void
00753 LogAccess::marshal_str(char *dest, const char *source, int padded_len)
00754 {
00755   if (source == NULL || source[0] == 0 || padded_len == 0) {
00756     source = DEFAULT_STR;
00757   }
00758   ink_strlcpy(dest, source, padded_len);
00759 
00760 #ifdef DEBUG
00761   //
00762   // what padded_len should be, if there is no padding, is strlen()+1.
00763   // if not, then we needed to pad and should touch the intermediate
00764   // bytes to avoid UMR errors when the buffer is written.
00765   //
00766   size_t real_len = (::strlen(source) + 1);
00767   while ((int) real_len < padded_len) {
00768     dest[real_len] = '$';
00769     real_len++;
00770   }
00771 #endif
00772 }
00773 
00774 /*-------------------------------------------------------------------------
00775   LogAccess::marshal_mem
00776 
00777   This is a version of marshal_str that works with unterminated strings.
00778   In this case, we'll copy the buffer and then add a trailing null that
00779   the rest of the system assumes.
00780   -------------------------------------------------------------------------*/
00781 
00782 void
00783 LogAccess::marshal_mem(char *dest, const char *source, int actual_len, int padded_len)
00784 {
00785   if (source == NULL || source[0] == 0 || actual_len == 0) {
00786     source = DEFAULT_STR;
00787     actual_len = DEFAULT_STR_LEN;
00788     ink_assert(actual_len < padded_len);
00789   }
00790   memcpy(dest, source, actual_len);
00791   dest[actual_len] = 0;         // add terminating null
00792 
00793 #ifdef DEBUG
00794   //
00795   // what len should be, if there is no padding, is strlen()+1.
00796   // if not, then we needed to pad and should touch the intermediate
00797   // bytes to avoid UMR errors when the buffer is written.
00798   //
00799   int real_len = actual_len + 1;
00800   while (real_len < padded_len) {
00801     dest[real_len] = '$';
00802     real_len++;
00803   }
00804 #endif
00805 }
00806 
00807 /*-------------------------------------------------------------------------
00808   LogAccess::marshal_ip
00809 
00810   Marshal an IP address in a reasonably compact way. If the address isn't
00811   valid (NULL or not IP) then marshal an invalid address record.
00812   -------------------------------------------------------------------------*/
00813 
00814 int
00815 LogAccess::marshal_ip(char* dest, sockaddr const* ip) {
00816   LogFieldIpStorage data;
00817   int len = sizeof(data._ip);
00818   if (NULL == ip) {
00819     data._ip._family = AF_UNSPEC;
00820   } else if (ats_is_ip4(ip)) {
00821     if (dest) {
00822       data._ip4._family = AF_INET;
00823       data._ip4._addr = ats_ip4_addr_cast(ip);
00824     }
00825     len = sizeof(data._ip4);
00826   } else if (ats_is_ip6(ip)) {
00827     if (dest) {
00828       data._ip6._family = AF_INET6;
00829       data._ip6._addr = ats_ip6_addr_cast(ip);
00830     }
00831     len = sizeof(data._ip6);
00832   } else {
00833     data._ip._family = AF_UNSPEC;
00834   }
00835 
00836   if (dest) memcpy(dest, &data, len);
00837   return INK_ALIGN_DEFAULT(len);
00838 }
00839 
00840 inline int
00841 LogAccess::unmarshal_with_map(int64_t code, char *dest, int len, Ptr<LogFieldAliasMap> map, const char *msg)
00842 {
00843   int codeStrLen;
00844 
00845   switch (map->asString(code, dest, len, (size_t *) & codeStrLen)) {
00846   case LogFieldAliasMap::INVALID_INT:
00847     if (msg) {
00848       const int bufSize = 64;
00849       char invalidCodeMsg[bufSize];
00850       codeStrLen = snprintf(invalidCodeMsg, 64, "%s(%" PRId64 ")", msg, code);
00851       if (codeStrLen < bufSize && codeStrLen < len) {
00852         ink_strlcpy(dest, invalidCodeMsg, len);
00853       } else {
00854         codeStrLen = -1;
00855       }
00856     } else {
00857       codeStrLen = -1;
00858     }
00859     break;
00860   case LogFieldAliasMap::BUFFER_TOO_SMALL:
00861     codeStrLen = -1;
00862     break;
00863   }
00864 
00865   return codeStrLen;
00866 }
00867 
00868 /*-------------------------------------------------------------------------
00869   LogAccess::unmarshal_int
00870 
00871   Return the integer pointed at by the buffer and advance the buffer
00872   pointer past the int.  The int will be converted back to host byte order.
00873   -------------------------------------------------------------------------*/
00874 
00875 int64_t
00876 LogAccess::unmarshal_int(char **buf)
00877 {
00878   ink_assert(buf != NULL);
00879   ink_assert(*buf != NULL);
00880   int64_t val;
00881 
00882   // TODO: this used to do nthol, do we need to worrry? TS-1156.
00883   val = *((int64_t *)(*buf));
00884   *buf += INK_MIN_ALIGN;
00885   return val;
00886 }
00887 
00888 /*-------------------------------------------------------------------------
00889   unmarshal_itoa
00890 
00891   This routine provides a fast conversion from a binary int to a string.
00892   It returns the number of characters formatted.  "dest" must point to the
00893   LAST character of an array large enough to store the complete formatted
00894   number.
00895   -------------------------------------------------------------------------*/
00896 
00897 int
00898 LogAccess::unmarshal_itoa(int64_t val, char *dest, int field_width, char leading_char)
00899 {
00900   ink_assert(dest != NULL);
00901 
00902   char *p = dest;
00903 
00904   if (val <= 0) {
00905     *p-- = '0';
00906     while (dest - p < field_width) {
00907       *p-- = leading_char;
00908     }
00909     return (int)(dest - p);
00910   }
00911 
00912   while (val) {
00913     *p-- = '0' + (val % 10);
00914     val /= 10;
00915   }
00916   while (dest - p < field_width) {
00917     *p-- = leading_char;
00918   }
00919   return (int)(dest - p);
00920 }
00921 
00922 /*-------------------------------------------------------------------------
00923   unmarshal_itox
00924 
00925   This routine provides a fast conversion from a binary int to a hex string.
00926   It returns the number of characters formatted.  "dest" must point to the
00927   LAST character of an array large enough to store the complete formatted
00928   number.
00929   -------------------------------------------------------------------------*/
00930 
00931 int
00932 LogAccess::unmarshal_itox(int64_t val, char *dest, int field_width, char leading_char)
00933 {
00934   ink_assert(dest != NULL);
00935 
00936   char *p = dest;
00937   static char table[] = "0123456789abcdef?";
00938 
00939   for (int i = 0; i < (int)(sizeof(int64_t) * 2); i++) {
00940     *p-- = table[val & 0xf];
00941     val >>= 4;
00942   }
00943   while (dest - p < field_width) {
00944     *p-- = leading_char;
00945   }
00946 
00947   return (int64_t)(dest - p);
00948 }
00949 
00950 /*-------------------------------------------------------------------------
00951   LogAccess::unmarshal_int_to_str
00952 
00953   Return the string representation of the integer pointed at by buf.
00954   -------------------------------------------------------------------------*/
00955 
00956 int
00957 LogAccess::unmarshal_int_to_str(char **buf, char *dest, int len)
00958 {
00959   ink_assert(buf != NULL);
00960   ink_assert(*buf != NULL);
00961   ink_assert(dest != NULL);
00962 
00963   char val_buf[128];
00964   int64_t val = unmarshal_int(buf);
00965   int val_len = unmarshal_itoa(val, val_buf + 127);
00966 
00967   if (val_len < len) {
00968     memcpy(dest, val_buf + 128 - val_len, val_len);
00969     return val_len;
00970   }
00971   return -1;
00972 }
00973 
00974 /*-------------------------------------------------------------------------
00975   LogAccess::unmarshal_int_to_str_hex
00976 
00977   Return the string representation (hexadecimal) of the integer pointed at by buf.
00978   -------------------------------------------------------------------------*/
00979 
00980 int
00981 LogAccess::unmarshal_int_to_str_hex(char **buf, char *dest, int len)
00982 {
00983   ink_assert(buf != NULL);
00984   ink_assert(*buf != NULL);
00985   ink_assert(dest != NULL);
00986 
00987   char val_buf[128];
00988   int64_t val = unmarshal_int(buf);
00989   int val_len = unmarshal_itox(val, val_buf + 127);
00990 
00991   if (val_len < len) {
00992     memcpy(dest, val_buf + 128 - val_len, val_len);
00993     return val_len;
00994   }
00995   return -1;
00996 }
00997 
00998 
00999 
01000 /*-------------------------------------------------------------------------
01001   LogAccess::unmarshal_str
01002 
01003   Retrieve the string from the location pointed at by the buffer and
01004   advance the pointer past the string.  The local strlen function is used
01005   to advance the pointer, thus matching the corresponding strlen that was
01006   used to lay the string into the buffer.
01007   -------------------------------------------------------------------------*/
01008 
01009 int
01010 LogAccess::unmarshal_str(char **buf, char *dest, int len, LogSlice *slice)
01011 {
01012   ink_assert(buf != NULL);
01013   ink_assert(*buf != NULL);
01014   ink_assert(dest != NULL);
01015 
01016   char *val_buf = *buf;
01017   int val_len = (int)::strlen(val_buf);
01018 
01019   *buf += LogAccess::strlen(val_buf);   // this is how it was stored
01020 
01021   if (slice && slice->m_enable) {
01022     int offset, n;
01023 
01024     n = slice->toStrOffset(val_len, &offset);
01025     if (n <= 0)
01026       return 0;
01027 
01028     if (n >= len)
01029       return -1;
01030 
01031     memcpy(dest, (val_buf + offset), n);
01032     return n;
01033   }
01034 
01035   if (val_len < len) {
01036     memcpy(dest, val_buf, val_len);
01037     return val_len;
01038   }
01039   return -1;
01040 }
01041 
01042 int
01043 LogAccess::unmarshal_ttmsf(char **buf, char *dest, int len)
01044 {
01045   ink_assert(buf != NULL);
01046   ink_assert(*buf != NULL);
01047   ink_assert(dest != NULL);
01048 
01049   int64_t val = unmarshal_int(buf);
01050   float secs = (float) val / 1000;
01051   int val_len = snprintf(dest, len, "%.3f", secs);
01052   return val_len;
01053 }
01054 
01055 /*-------------------------------------------------------------------------
01056   LogAccess::unmarshal_http_method
01057 
01058   Retrieve the int pointed at by the buffer and treat as an HttpMethod
01059   enumerated type.  Then lookup the string representation for that enum and
01060   return the string.  Advance the buffer pointer past the enum.
01061   -------------------------------------------------------------------------*/
01062 /*
01063 int
01064 LogAccess::unmarshal_http_method (char **buf, char *dest, int len)
01065 {
01066     return unmarshal_str (buf, dest, len);
01067 }
01068 */
01069 /*-------------------------------------------------------------------------
01070   LogAccess::unmarshal_http_version
01071 
01072   The http version is marshalled as two consecutive integers, the first for
01073   the major number and the second for the minor number.  Retrieve both
01074   numbers and return the result as "HTTP/major.minor".
01075   -------------------------------------------------------------------------*/
01076 
01077 int
01078 LogAccess::unmarshal_http_version(char **buf, char *dest, int len)
01079 {
01080   ink_assert(buf != NULL);
01081   ink_assert(*buf != NULL);
01082   ink_assert(dest != NULL);
01083 
01084   static const char *http = "HTTP/";
01085   static int http_len = (int)::strlen(http);
01086 
01087   char val_buf[128];
01088   char *p = val_buf;
01089 
01090   memcpy(p, http, http_len);
01091   p += http_len;
01092 
01093   int res1 = unmarshal_int_to_str(buf, p, 128 - http_len);
01094   if (res1 < 0) {
01095     return -1;
01096   }
01097   p += res1;
01098   *p++ = '.';
01099   int res2 = unmarshal_int_to_str(buf, p, 128 - http_len - res1 - 1);
01100   if (res2 < 0) {
01101     return -1;
01102   }
01103 
01104   int val_len = http_len + res1 + res2 + 1;
01105   if (val_len < len) {
01106     memcpy(dest, val_buf, val_len);
01107     return val_len;
01108   }
01109   return -1;
01110 }
01111 
01112 /*-------------------------------------------------------------------------
01113   LogAccess::unmarshal_http_text
01114 
01115   The http text is simply the fields http_method (cqhm) + url (cqu) +
01116   http_version (cqhv), all right next to each other, in that order.
01117   -------------------------------------------------------------------------*/
01118 
01119 int
01120 LogAccess::unmarshal_http_text(char **buf, char *dest, int len, LogSlice *slice)
01121 {
01122   ink_assert(buf != NULL);
01123   ink_assert(*buf != NULL);
01124   ink_assert(dest != NULL);
01125 
01126   char *p = dest;
01127 
01128 //    int res1 = unmarshal_http_method (buf, p, len);
01129   int res1 = unmarshal_str(buf, p, len);
01130   if (res1 < 0) {
01131     return -1;
01132   }
01133   p += res1;
01134   *p++ = ' ';
01135   int res2 = unmarshal_str(buf, p, len - res1 - 1, slice);
01136   if (res2 < 0) {
01137     return -1;
01138   }
01139   p += res2;
01140   *p++ = ' ';
01141   int res3 = unmarshal_http_version(buf, p, len - res1 - res2 - 2);
01142   if (res3 < 0) {
01143     return -1;
01144   }
01145   return res1 + res2 + res3 + 2;
01146 }
01147 
01148 /*-------------------------------------------------------------------------
01149   LogAccess::unmarshal_http_status
01150 
01151   An http response status code (pssc,sssc) is just an INT, but it's always
01152   formatted with three digits and leading zeros.  So, we need a special
01153   version of unmarshal_int_to_str that does this leading zero formatting.
01154   -------------------------------------------------------------------------*/
01155 
01156 int
01157 LogAccess::unmarshal_http_status(char **buf, char *dest, int len)
01158 {
01159   ink_assert(buf != NULL);
01160   ink_assert(*buf != NULL);
01161   ink_assert(dest != NULL);
01162 
01163   char val_buf[128];
01164   int64_t val = unmarshal_int(buf);
01165   int val_len = unmarshal_itoa(val, val_buf + 127, 3, '0');
01166   if (val_len < len) {
01167     memcpy(dest, val_buf + 128 - val_len, val_len);
01168     return val_len;
01169   }
01170   return -1;
01171 }
01172 
01173 /*-------------------------------------------------------------------------
01174   LogAccess::unmarshal_ip
01175 
01176   Retrieve an IP address directly.
01177   -------------------------------------------------------------------------*/
01178 int
01179 LogAccess::unmarshal_ip(char **buf, IpEndpoint* dest)
01180 {
01181   int len = sizeof(LogFieldIp); // of object processed.
01182 
01183   ink_assert(buf != NULL);
01184   ink_assert(*buf != NULL);
01185   ink_assert(dest != NULL);
01186 
01187   LogFieldIp* raw = reinterpret_cast<LogFieldIp*>(*buf);
01188   if (AF_INET == raw->_family) {
01189     LogFieldIp4* ip4 = static_cast<LogFieldIp4*>(raw);
01190     ats_ip4_set(dest, ip4->_addr);
01191     len = sizeof(*ip4);
01192   } else if (AF_INET6 == raw->_family) {
01193     LogFieldIp6* ip6 = static_cast<LogFieldIp6*>(raw);
01194     ats_ip6_set(dest, ip6->_addr);
01195     len = sizeof(*ip6);
01196   } else {
01197     ats_ip_invalidate(dest);
01198   }
01199   len = INK_ALIGN_DEFAULT(len);
01200   *buf += len;
01201   return len;
01202 }
01203 
01204 /*-------------------------------------------------------------------------
01205   LogAccess::unmarshal_ip_to_str
01206 
01207   Retrieve the IP addresspointed at by the buffer and convert to a
01208   string in standard format. The string is written to @a dest and its
01209   length (not including nul) is returned. @a *buf is advanced.
01210   -------------------------------------------------------------------------*/
01211 
01212 int
01213 LogAccess::unmarshal_ip_to_str(char **buf, char *dest, int len)
01214 {
01215   IpEndpoint ip;
01216   int zret = -1;
01217 
01218   if (len > 0) {
01219     unmarshal_ip(buf, &ip);
01220     if (!ats_is_ip(&ip)) {
01221       *dest = '0';
01222       zret = 1;
01223     } else if (ats_ip_ntop(&ip, dest, len)) {
01224       zret = static_cast<int>(::strlen(dest));
01225     }
01226   }
01227   return zret;
01228 }
01229 
01230 /*-------------------------------------------------------------------------
01231   LogAccess::unmarshal_ip_to_hex
01232 
01233   Retrieve the int pointed at by the buffer and treat as an IP
01234   address.  Convert to a string in byte oriented hexadeciaml and
01235   return the string.  Advance the buffer pointer.
01236   -------------------------------------------------------------------------*/
01237 
01238 int
01239 LogAccess::unmarshal_ip_to_hex(char **buf, char *dest, int len)
01240 {
01241   int zret = -1;
01242   IpEndpoint ip;
01243 
01244   if (len > 0) {
01245     unmarshal_ip(buf, &ip);
01246     if (!ats_is_ip(&ip)) {
01247       *dest = '0';
01248       zret = 1;
01249     } else {
01250       zret = ats_ip_to_hex(&ip.sa, dest, len);
01251     }
01252   }
01253   return zret;
01254 }
01255 
01256 /*-------------------------------------------------------------------------
01257   LogAccess::unmarshal_hierarchy
01258 
01259   Retrieve the int pointed at by the buffer and treat as a
01260   SquidHierarchyCode.  Use this as an index into the local string
01261   conversion tables and return the string equivalent to the enum.
01262   Advance the buffer pointer.
01263   -------------------------------------------------------------------------*/
01264 
01265 int
01266 LogAccess::unmarshal_hierarchy(char **buf, char *dest, int len, Ptr<LogFieldAliasMap> map)
01267 {
01268   ink_assert(buf != NULL);
01269   ink_assert(*buf != NULL);
01270   ink_assert(dest != NULL);
01271 
01272   return (LogAccess::unmarshal_with_map(unmarshal_int(buf), dest, len, map, "INVALID_CODE"));
01273 }
01274 
01275 /*-------------------------------------------------------------------------
01276   LogAccess::unmarshal_finish_status
01277 
01278   Retrieve the int pointed at by the buffer and treat as a finish code.
01279   Use the enum as an index into a string table and return the string equiv
01280   of the enum.  Advance the pointer.
01281   -------------------------------------------------------------------------*/
01282 
01283 int
01284 LogAccess::unmarshal_finish_status(char **buf, char *dest, int len, Ptr<LogFieldAliasMap> map)
01285 {
01286   ink_assert(buf != NULL);
01287   ink_assert(*buf != NULL);
01288   ink_assert(dest != NULL);
01289 
01290   return (LogAccess::unmarshal_with_map(unmarshal_int(buf), dest, len, map, "UNKNOWN_FINISH_CODE"));
01291 }
01292 
01293 
01294 /*-------------------------------------------------------------------------
01295   LogAccess::unmarshal_cache_code
01296 
01297   Retrieve the int pointed at by the buffer and treat as a SquidLogCode.
01298   Use this to index into the local string tables and return the string
01299   equiv of the enum.  Advance the pointer.
01300   -------------------------------------------------------------------------*/
01301 
01302 int
01303 LogAccess::unmarshal_cache_code(char **buf, char *dest, int len, Ptr<LogFieldAliasMap> map)
01304 {
01305   ink_assert(buf != NULL);
01306   ink_assert(*buf != NULL);
01307   ink_assert(dest != NULL);
01308 
01309   return (LogAccess::unmarshal_with_map(unmarshal_int(buf), dest, len, map, "ERROR_UNKNOWN"));
01310 }
01311 
01312 /*-------------------------------------------------------------------------
01313   LogAccess::unmarshal_entry_type
01314   -------------------------------------------------------------------------*/
01315 
01316 int
01317 LogAccess::unmarshal_entry_type(char **buf, char *dest, int len, Ptr<LogFieldAliasMap> map)
01318 {
01319   ink_assert(buf != NULL);
01320   ink_assert(*buf != NULL);
01321   ink_assert(dest != NULL);
01322 
01323   return (LogAccess::unmarshal_with_map(unmarshal_int(buf), dest, len, map, "UNKNOWN_ENTRY_TYPE"));
01324 }
01325 
01326 int
01327 LogAccess::unmarshal_cache_write_code(char **buf, char *dest, int len, Ptr<LogFieldAliasMap> map)
01328 {
01329   ink_assert(buf != NULL);
01330   ink_assert(*buf != NULL);
01331   ink_assert(dest != NULL);
01332 
01333   return (LogAccess::unmarshal_with_map(unmarshal_int(buf), dest, len, map, "UNKNOWN_CACHE_WRITE_CODE"));
01334 }
01335 
01336 int
01337 LogAccess::unmarshal_record(char **buf, char *dest, int len)
01338 {
01339   ink_assert(buf != NULL);
01340   ink_assert(*buf != NULL);
01341   ink_assert(dest != NULL);
01342 
01343   char *val_buf = *buf;
01344   int val_len = (int)::strlen(val_buf);
01345   *buf += MARSHAL_RECORD_LENGTH;        // this is how it was stored
01346   if (val_len < len) {
01347     memcpy(dest, val_buf, val_len);
01348     return val_len;
01349   }
01350   return -1;
01351 }
01352 
01353 /*-------------------------------------------------------------------------
01354   resolve_logfield_string
01355 
01356   This function resolves the given custom log format string using the given
01357   LogAccess context and returns the resulting string, which is ats_malloc'd.
01358   The caller is responsible for ats_free'ing the return result.  If there are
01359   any problems, NULL is returned.
01360   -------------------------------------------------------------------------*/
01361 char *
01362 resolve_logfield_string(LogAccess *context, const char *format_str)
01363 {
01364   if (!context) {
01365     Debug("log-resolve", "No context to resolve?");
01366     return NULL;
01367   }
01368 
01369   if (!format_str) {
01370     Debug("log-resolve", "No format to resolve?");
01371     return NULL;
01372   }
01373 
01374   Debug("log-resolve", "Resolving: %s", format_str);
01375 
01376   //
01377   // Divide the format string into two parts: one for the printf-style
01378   // string and one for the symbols.
01379   //
01380   char *printf_str = NULL;
01381   char *fields_str = NULL;
01382   int n_fields = LogFormat::parse_format_string(format_str, &printf_str, &fields_str);
01383 
01384   //
01385   // Perhaps there were no fields to resolve?  Then just return the
01386   // format_str. Nothing to free here either.
01387   //
01388   if (!n_fields) {
01389     Debug("log-resolve", "No fields found; returning copy of format_str");
01390     ats_free(printf_str);
01391     ats_free(fields_str);
01392     return ats_strdup(format_str);
01393   }
01394 
01395   Debug("log-resolve", "%d fields: %s", n_fields, fields_str);
01396   Debug("log-resolve", "printf string: %s", printf_str);
01397 
01398   LogFieldList fields;
01399   bool contains_aggregates;
01400   int field_count = LogFormat::parse_symbol_string(fields_str, &fields, &contains_aggregates);
01401 
01402   if (field_count != n_fields) {
01403     Error("format_str contains %d invalid field symbols", n_fields - field_count);
01404     ats_free(printf_str);
01405     ats_free(fields_str);
01406     return NULL;
01407   }
01408   //
01409   // Ok, now marshal the data out of the LogAccess object and into a
01410   // temporary storage buffer.  Make sure the LogAccess context is
01411   // initialized first.
01412   //
01413   Debug("log-resolve", "Marshaling data from LogAccess into buffer ...");
01414   context->init();
01415   unsigned bytes_needed = fields.marshal_len(context);
01416   char *buf = (char *) ats_malloc(bytes_needed);
01417   unsigned bytes_used = fields.marshal(context, buf);
01418 
01419   ink_assert(bytes_needed == bytes_used);
01420   Debug("log-resolve", "    %u bytes marshalled", bytes_used);
01421 
01422   //
01423   // Now we can "unmarshal" the data from the buffer into a string,
01424   // combining it with the data from the printf string.  The problem is,
01425   // we're not sure how much space it will take when it's unmarshalled.
01426   // So, we'll just guess.
01427   //
01428   char *result = (char *) ats_malloc(8192);
01429   unsigned bytes_resolved = LogBuffer::resolve_custom_entry(&fields, printf_str, buf, result,
01430                                                             8191, LogUtils::timestamp(), 0,
01431                                                             LOG_SEGMENT_VERSION);
01432   ink_assert(bytes_resolved < 8192);
01433 
01434   if (!bytes_resolved) {
01435     ats_free(result);
01436     result = NULL;
01437   } else
01438     result[bytes_resolved] = 0; // NULL terminate
01439 
01440   ats_free(printf_str);
01441   ats_free(fields_str);
01442   ats_free(buf);
01443 
01444   return result;
01445 }

Generated by  doxygen 1.7.1