Google APIs Client Library for C++
json_scribe.h
Go to the documentation of this file.
00001 /*
00002  * \copyright Copyright 2013 Google Inc. All Rights Reserved.
00003  * \license @{
00004  *
00005  * Licensed under the Apache License, Version 2.0 (the "License");
00006  * you may not use this file except in compliance with the License.
00007  * You may obtain a copy of the License at
00008  *
00009  *     http://www.apache.org/licenses/LICENSE-2.0
00010  *
00011  * Unless required by applicable law or agreed to in writing, software
00012  * distributed under the License is distributed on an "AS IS" BASIS,
00013  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00014  * See the License for the specific language governing permissions and
00015  * limitations under the License.
00016  *
00017  * @}
00018  */
00019 
00020 
00021 #ifndef APISERVING_CLIENTS_CPP_TRANSPORT_JSON_SCRIBE_H_
00022 #define APISERVING_CLIENTS_CPP_TRANSPORT_JSON_SCRIBE_H_
00023 
00024 #include <string>
00025 using std::string;
00026 
00027 #include "googleapis/client/transport/http_scribe.h"
00028 #include "googleapis/base/thread_annotations.h"
00029 #include "googleapis/base/integral_types.h"
00030 #include "googleapis/base/scoped_ptr.h"
00031 #include "googleapis/strings/strcat.h"
00032 #include "googleapis/strings/stringpiece.h"
00033 #include <json/value.h>
00034 #include <json/writer.h>
00035 namespace googleapis {
00036 
00037 namespace client {
00038 class DataWriter;
00039 
00040 /*
00041  * Specialized HttpScribe that produces JSON transcripts.
00042  * @ingroup TransportLayerTesting
00043  *
00044  * The scribe writes JSON directly to the writer. It does not proovide
00045  * an interactive interface to interpret the JSON it is writing. In order
00046  * to see the events, you must look at the writer.
00047  *
00048  * The implementation of this class may stream directly to the writer, in
00049  * which case it may not be well-formed if it did not finish properly
00050  * (e.g. it is still scribing or the process crashed). If that is the case,
00051  * you may need to  append the closing brackets and braces to make it well
00052  * formed if you wish to read it back as json.
00053  *
00054  * The transcript has the following JSON structure:
00055  *    {
00056  *       kStartTime : datetime
00057  *       kMaxSnippet: int64
00058  *       kMessages : [
00059  *         {
00060  *           kUrl : string
00061  *           kHttpCode : int           # none or 0 if no response
00062  *           kStatusCode : int         # transport error, if any
00063  *           kStatusMessage : string   # transport error, if any
00064  *           kRequest : {
00065  *             kHeaders : [
00066  *               string : string     # name, value pairs
00067  *               string : string
00068  *             ]
00069  *             kBytes : string
00070  *             kSize  : int64
00071  *             kCensored  : bool
00072  *           }
00073  *           kResponse : {
00074  *              (same as request but for response data)
00075  *           }
00076  *       ]
00077  *       kEndTime   : datetime
00078  *    }
00079  *
00080  * The individual fields are documented as class constants. Each constant also
00081  * documents the JSON format for the values.
00082  */
00083 class JsonScribe : public HttpEntryScribe {
00084  public:
00085   /*
00086    * Constructor.
00087    *
00088    * @param[in] censor The caller retains ownership.
00089    * @param[in] writer Ownership is passed to the scribe. This writer will
00090    *            store the transcript.
00091    * @param[in] compact If truen then write compact json, otherwise stylized.
00092    */
00093   JsonScribe(
00094       HttpScribeCensor* censor, DataWriter* writer, bool compact = true);
00095 
00096   /*
00097    * Standard destructor.
00098    *
00099    * This will finish the JSON and flush the writer to make a well formed
00100    * JSON document transcript.
00101    */
00102   virtual ~JsonScribe();
00103 
00104   /*
00105    * Implements base Checkpoint method.
00106    */
00107   virtual void Checkpoint();
00108 
00109   //-------------------------  JSON Tag Constants  -------------------------
00110 
00111   static const char kStartTime[];  //< The transcript start time (date).
00112   static const char kMaxSnippet[];  //< The max_snippet size used (int64).
00113   static const char kEndTime[];    //< The transcript end time   (date).
00114   /*
00115    * The JSON object tag for the message sequence.
00116    *
00117    * The message sequence is a JSON array object where each element in the
00118    * array is a flat dictionary containing the per-request attributes.
00119    */
00120   static const char kMessages[];
00121 
00122   static const char kMethod[];     //< Request HTTP method type (string).
00123   static const char kUrl[];        //< Request url (string).
00124 
00125   /*
00126    * The HTTP response code, if any (int).
00127    *
00128    * If this tag is not present, or the value is 0, then a response was not
00129    * received. This could be because of a transport error in which case
00130    * the kStatusCode and kStatusMessage fields should be present. Otherwise
00131    * it means that a response was not yet recorded for whatever reason
00132    * including the transcript was finished before the request completed.
00133    */
00134   static const char kHttpCode[];
00135 
00136   /*
00137    * The transport util::Status::error_code value (int).
00138    *
00139    * An error here indicates a transport error when sending the request.
00140    * The response was either never received or the request was never sent.
00141    *
00142    * Note that the status codes that specific errors produce is not yet
00143    * well defined so may change from release to release. The StatusMessage
00144    * will be of more value if you are physically inspecting these messages.
00145    *
00146    * A value of 0 indicates everything was ok. This is the only well defined
00147    * value that will not change in future releases. If this field is not
00148    * present, then the transport status is assumed to be OK.
00149    *
00150    * @see HttpRequestState::transport_status
00151    */
00152   static const char kStatusCode[];
00153 
00154   /*
00155    * The transport util::Status::error_message value (string).
00156    *
00157    * If this is present and not empty then it gives an explanation for the
00158    * transport status. This is usually an error but not necessarily. The
00159    * kStatusCode field will indicate whether it is ok or not.
00160    *
00161    * The message values are intended to be human readable and may change from
00162    * release to release.
00163    */
00164   static const char kStatusMessage[];
00165 
00166   /*
00167    * Timestamp request was sent in microseconds since the epoch (int64).
00168    */
00169   static const char kSendMicros[];
00170 
00171   /*
00172    * Timestamp response was received in microseconds since the epoch (int64).
00173    */
00174   static const char kResponseMicros[];
00175 
00176   /*
00177    * Timestamp of transport error in microseconds since the epoch (int64).
00178    */
00179   static const char kErrorMicros[];
00180 
00181   static const char kRequest[];    //< Message request (dict).
00182   static const char kResponse[];   //< Message response (dict).
00183 
00184   // These are fields within the request and response dictionaries.
00185   static const char kPayload[];        //< Message payload data.
00186   static const char kPayloadSize[];    //< Real request payload size (int64).
00187   static const char kPayloadCensored[];  //< True if censored (bool).
00188   static const char kHeaders[];          //< Headers (dict). (
00189 
00190  protected:
00191   /*
00192    * Returns an entry that produces the individual JSON transcript for
00193    * the request.
00194    */
00195   virtual Entry* NewEntry(const HttpRequest* request);
00196 
00197  private:
00198   scoped_ptr<DataWriter> writer_;
00199   scoped_ptr<Json::Writer> json_writer_;
00200   int64 last_checkpoint_;
00201   bool  started_;
00202   Json::Value json_;
00203 };
00204 
00205 }  // namespace client
00206 
00207 } // namespace googleapis
00208 #endif  // APISERVING_CLIENTS_CPP_TRANSPORT_JSON_SCRIBE_H_
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines