Bug fixes. Explain document in config. Logging changes - dsp elapsed time.
authorAdam Dickmeiss <adam@indexdata.dk>
Mon, 22 Dec 2003 15:16:23 +0000 (15:16 +0000)
committerAdam Dickmeiss <adam@indexdata.dk>
Mon, 22 Dec 2003 15:16:23 +0000 (15:16 +0000)
etc/config.xml
include/yaz++/proxy.h
src/yaz-proxy-config.cpp
src/yaz-proxy.cpp

index b388bdc..7c8d1ef 100644 (file)
@@ -1,8 +1,7 @@
 <?xml version="1.0"?>
-<!-- $Id: config.xml,v 1.3 2003-12-20 22:44:30 adam Exp $ -->
+<!-- $Id: config.xml,v 1.4 2003-12-22 15:16:23 adam Exp $ -->
 <proxy>
   <target name="bagel">
-    <!-- default target -->
     <url>indexdata.dk</url>
     <target-timeout>240</target-timeout>
     <client-timeout>180</client-timeout>
@@ -28,6 +27,7 @@
   </target>
   <target default="1" name="localhost">
     <url>localhost:9999</url>
+    <url>localhost:9998</url>
     <target-timeout>300</target-timeout>
     <client-timeout>180</client-timeout>
     <keepalive/> <!-- keepalive enabled -->
     <syntax type="*" error="238"/>
     <preinit>2</preinit>
     <cql2rpn>pqf.properties</cql2rpn>
+    <explain>
+      <serverInfo>
+       <host>myhost</host>
+      </serverInfo>
+    </explain>
     <zeerex>zeerex.xml</zeerex>
   </target>
   <target name="*">
     <!-- everything else -->
   </target>
   <max-clients>50</max-clients>
+  <log>client-requests server-requests</log>
 </proxy>
index c40f3e6..657b7ef 100644 (file)
@@ -2,9 +2,10 @@
  * Copyright (c) 1998-2003, Index Data.
  * See the file LICENSE for details.
  * 
- * $Id: proxy.h,v 1.23 2003-12-20 22:44:30 adam Exp $
+ * $Id: proxy.h,v 1.24 2003-12-22 15:16:23 adam Exp $
  */
 
+#include <sys/time.h>
 #include <yaz++/z-assoc.h>
 #include <yaz++/z-query.h>
 #include <yaz++/z-databases.h>
@@ -43,8 +44,7 @@ public:
                      int *keepalive_limit_bw,
                      int *keepalive_limit_pdu,
                      int *pre_init,
-                     const char **cql2rpn,
-                     const char **zeerex);
+                     const char **cql2rpn);
     
     void get_generic_info(int *log_mask, int *max_clients);
 
@@ -54,12 +54,13 @@ public:
                         int *max_clients,
                         int *keepalive_limit_bw, int *keepalive_limit_pdu,
                         int *pre_init,
-                        const char **cql2rpn,
-                        const char **zeerex);
+                        const char **cql2rpn);
 
     int check_query(ODR odr, const char *name, Z_Query *query, char **addinfo);
     int check_syntax(ODR odr, const char *name,
                     Odr_oid *syntax, char **addinfo);
+    char *get_explain(ODR odr, const char *name, const char *db,
+                     int *len);
 private:
     void operator=(const Yaz_ProxyConfig &conf);
     int mycmp(const char *hay, const char *item, size_t len);
@@ -70,13 +71,13 @@ private:
                            int *limit_bw, int *limit_pdu, int *limit_req,
                            int *target_idletime, int *client_idletime,
                            int *keepalive_limit_bw, int *keepalive_limit_pdu,
-                           int *pre_init, const char **cql2rpn,
-                           const char **zeerex);
+                           int *pre_init, const char **cql2rpn);
     void return_limit(xmlNodePtr ptr,
                      int *limit_bw, int *limit_pdu, int *limit_req);
     int check_type_1(ODR odr, xmlNodePtr ptr, Z_RPNQuery *query,
                     char **addinfo);
-    xmlNodePtr find_target_node(const char *name);
+    xmlNodePtr find_target_node(const char *name, const char *db);
+    xmlNodePtr find_target_db(xmlNodePtr ptr, const char *db);
     const char *get_text(xmlNodePtr ptr);
     int check_type_1_attributes(ODR odr, xmlNodePtr ptr,
                                Z_AttributeList *attrs,
@@ -258,11 +259,13 @@ class YAZ_EXPORT Yaz_Proxy : public Yaz_Z_Assoc {
     int m_http_keepalive;
     const char *m_http_version;
     Yaz_cql2rpn m_cql2rpn;
-    const char *m_zeerex_fname;
+    struct timeval m_time_tv;
+    void logtime();
  public:
     Yaz_Proxy(IYaz_PDU_Observable *the_PDU_Observable,
              Yaz_Proxy *parent = 0);
     ~Yaz_Proxy();
+    void inc_request_no();
     void recv_GDU(Z_GDU *apdu, int len);
     void handle_incoming_HTTP(Z_HTTP_Request *req);
     void handle_incoming_Z_PDU(Z_APDU *apdu);
index b824462..96695fc 100644 (file)
@@ -2,7 +2,7 @@
  * Copyright (c) 1998-2003, Index Data.
  * See the file LICENSE for details.
  * 
- * $Id: yaz-proxy-config.cpp,v 1.16 2003-12-20 22:44:30 adam Exp $
+ * $Id: yaz-proxy-config.cpp,v 1.17 2003-12-22 15:16:23 adam Exp $
  */
 
 #include <ctype.h>
@@ -118,8 +118,7 @@ void Yaz_ProxyConfig::return_target_info(xmlNodePtr ptr,
                                         int *keepalive_limit_bw,
                                         int *keepalive_limit_pdu,
                                         int *pre_init,
-                                        const char **cql2rpn,
-                                        const char **zeerex)
+                                        const char **cql2rpn)
 {
     *pre_init = 0;
     int no_url = 0;
@@ -183,13 +182,6 @@ void Yaz_ProxyConfig::return_target_info(xmlNodePtr ptr,
            if (t)
                *cql2rpn = t;
        }
-       if (ptr->type == XML_ELEMENT_NODE 
-           && !strcmp((const char *) ptr->name, "zeerex"))
-       {
-           const char *t = get_text(ptr);
-           if (t)
-               *zeerex = t;
-       }
     }
 }
 #endif
@@ -342,7 +334,7 @@ int Yaz_ProxyConfig::check_query(ODR odr, const char *name, Z_Query *query,
 #if HAVE_XML2
     xmlNodePtr ptr;
     
-    ptr = find_target_node(name);
+    ptr = find_target_node(name, 0);
     if (ptr)
     {
        if (query->which == Z_Query_type_1 || query->which == Z_Query_type_101)
@@ -358,7 +350,7 @@ int Yaz_ProxyConfig::check_syntax(ODR odr, const char *name,
 #if HAVE_XML2
     xmlNodePtr ptr;
     
-    ptr = find_target_node(name);
+    ptr = find_target_node(name, 0);
     if (!ptr)
        return 0;
     for(ptr = ptr->children; ptr; ptr = ptr->next)
@@ -425,7 +417,34 @@ int Yaz_ProxyConfig::check_syntax(ODR odr, const char *name,
 }
 
 #if HAVE_XML2
-xmlNodePtr Yaz_ProxyConfig::find_target_node(const char *name)
+xmlNodePtr Yaz_ProxyConfig::find_target_db(xmlNodePtr ptr, const char *db)
+{
+    xmlNodePtr dptr;
+    if (!db)
+       return ptr;
+    if (!ptr)
+       return 0;
+    for (dptr = ptr->children; dptr; dptr = dptr->next)
+       if (dptr->type == XML_ELEMENT_NODE &&
+           !strcmp((const char *) dptr->name, "database"))
+       {
+           struct _xmlAttr *attr;
+           for (attr = dptr->properties; attr; attr = attr->next)
+               if (!strcmp((const char *) attr->name, "name"))
+               {
+                   if (attr->children
+                       && attr->children->type==XML_TEXT_NODE
+                       && attr->children->content 
+                       && (!strcmp((const char *) attr->children->content, db)
+                           || !strcmp((const char *) attr->children->content,
+                                      "*")))
+                       return dptr;
+               }
+       }
+    return ptr;
+}
+    
+xmlNodePtr Yaz_ProxyConfig::find_target_node(const char *name, const char *db)
 {
     xmlNodePtr ptr;
     if (!m_proxyPtr)
@@ -446,7 +465,9 @@ xmlNodePtr Yaz_ProxyConfig::find_target_node(const char *name)
                    {
                        xmlChar *t = attr->children->content;
                        if (!t || *t == '1')
-                           return ptr;
+                       {
+                           return find_target_db(ptr, db);
+                       }
                    }
            }
            else
@@ -464,7 +485,7 @@ xmlNodePtr Yaz_ProxyConfig::find_target_node(const char *name)
                                || !strcmp((const char *) attr->children->content,
                                           "*")))
                        {
-                           return ptr;
+                           return find_target_db(ptr, db);
                        }
                    }
            }
@@ -486,8 +507,7 @@ int Yaz_ProxyConfig::get_target_no(int no,
                                   int *keepalive_limit_bw,
                                   int *keepalive_limit_pdu,
                                   int *pre_init,
-                                  const char **cql2rpn,
-                                  const char **zeerex)
+                                  const char **cql2rpn)
 {
 #if HAVE_XML2
     xmlNodePtr ptr;
@@ -512,7 +532,7 @@ int Yaz_ProxyConfig::get_target_no(int no,
                return_target_info(ptr, url, limit_bw, limit_pdu, limit_req,
                                   target_idletime, client_idletime,
                                   keepalive_limit_bw, keepalive_limit_pdu,
-                                  pre_init, cql2rpn, zeerex);
+                                  pre_init, cql2rpn);
                return 1;
            }
            i++;
@@ -580,6 +600,43 @@ void Yaz_ProxyConfig::get_generic_info(int *log_mask,
 #endif
 }
 
+char *Yaz_ProxyConfig::get_explain(ODR odr, const char *name, const char *db,
+                                  int *len)
+{
+#if HAVE_XML2
+    xmlNodePtr ptr = find_target_node(name, db);
+    if (ptr)
+    {
+       ptr = ptr->children;
+       for (; ptr; ptr = ptr->next)
+           if (ptr->type == XML_ELEMENT_NODE &&
+               !strcmp((const char *) ptr->name, "explain"))
+           {
+               xmlNodePtr ptr2 = xmlCopyNode(ptr, 1);
+
+               xmlDocPtr doc = xmlNewDoc((const xmlChar *) "1.0");
+               
+               xmlDocSetRootElement(doc, ptr2);
+               
+               xmlChar *buf_out;
+               int len_out;
+               xmlDocDumpMemory(doc, &buf_out, len);
+               char *content = (char*) odr_malloc(odr, *len);
+               memcpy(content, buf_out, *len);
+               
+               xmlFree(buf_out);
+               xmlFreeDoc(doc);
+               return content;
+           }
+    }
+    else
+       yaz_log(LOG_WARN, "No explain node 1");
+
+#endif
+    yaz_log(LOG_WARN, "No explain node");
+    return 0;
+}
+
 void Yaz_ProxyConfig::get_target_info(const char *name,
                                      const char **url,
                                      int *limit_bw,
@@ -591,8 +648,7 @@ void Yaz_ProxyConfig::get_target_info(const char *name,
                                      int *keepalive_limit_bw,
                                      int *keepalive_limit_pdu,
                                      int *pre_init,
-                                     const char **cql2rpn,
-                                     const char **zeerex)
+                                     const char **cql2rpn)
 {
 #if HAVE_XML2
     xmlNodePtr ptr;
@@ -617,7 +673,7 @@ void Yaz_ProxyConfig::get_target_info(const char *name,
            }
        }
     }
-    ptr = find_target_node(name);
+    ptr = find_target_node(name, 0);
     if (ptr)
     {
        if (name)
@@ -628,7 +684,7 @@ void Yaz_ProxyConfig::get_target_info(const char *name,
        return_target_info(ptr, url, limit_bw, limit_pdu, limit_req,
                           target_idletime, client_idletime,
                           keepalive_limit_bw, keepalive_limit_pdu,
-                          pre_init, cql2rpn, zeerex);
+                          pre_init, cql2rpn);
     }
 #else
     *url = name;
index 71dd336..808f0dd 100644 (file)
@@ -2,7 +2,7 @@
  * Copyright (c) 1998-2003, Index Data.
  * See the file LICENSE for details.
  * 
- * $Id: yaz-proxy.cpp,v 1.72 2003-12-20 22:44:30 adam Exp $
+ * $Id: yaz-proxy.cpp,v 1.73 2003-12-22 15:16:23 adam Exp $
  */
 
 #include <assert.h>
@@ -114,7 +114,8 @@ Yaz_Proxy::Yaz_Proxy(IYaz_PDU_Observable *the_PDU_Observable,
     m_http_version = 0;
     m_soap_ns = 0;
     m_s2z_packing = Z_SRW_recordPacking_string;
-    m_zeerex_fname = 0;
+    m_time_tv.tv_sec = 0;
+    m_time_tv.tv_usec = 0;
 }
 
 Yaz_Proxy::~Yaz_Proxy()
@@ -314,8 +315,7 @@ Yaz_ProxyClient *Yaz_Proxy::get_client(Z_APDU *apdu, const char *cookie,
                                 &m_keepalive_limit_bw,
                                 &m_keepalive_limit_pdu,
                                 &pre_init,
-                                &cql2rpn_fname,
-                                &m_zeerex_fname);
+                                &cql2rpn_fname);
        }
        if (client_idletime != -1)
        {
@@ -633,6 +633,22 @@ void Yaz_Proxy::convert_to_marcxml(Z_NamePlusRecordList *p)
     yaz_marc_destroy(mt);
 }
 
+void Yaz_Proxy::logtime()
+{
+    if (m_time_tv.tv_sec)
+    {
+       struct timeval tv;
+       gettimeofday(&tv, 0);
+       long diff = (tv.tv_sec - m_time_tv.tv_sec)*1000000 +
+           (tv.tv_usec - m_time_tv.tv_usec);
+       if (diff >= 0)
+           yaz_log(LOG_LOG, "%sElapsed %ld.%03ld", m_session_str,
+                   diff/1000000, (diff/1000)%1000);
+    }
+    m_time_tv.tv_sec = 0;
+    m_time_tv.tv_usec = 0;
+}
+
 int Yaz_Proxy::send_http_response(int code)
 {
     ODR o = odr_encode();
@@ -642,8 +658,15 @@ int Yaz_Proxy::send_http_response(int code)
     if (m_http_version)
        hres->version = odr_strdup(o, m_http_version);
     m_http_keepalive = 0;
+    if (m_log_mask & PROXY_LOG_REQ_CLIENT)
+    {
+       yaz_log (LOG_LOG, "%sSending %s to client", m_session_str,
+                gdu_name(gdu));
+    }
     int len;
-    return send_GDU(gdu, &len);
+    int r = send_GDU(gdu, &len);
+    logtime();
+    return r;
 }
 
 int Yaz_Proxy::send_srw_response(Z_SRW_PDU *srw_pdu)
@@ -677,8 +700,15 @@ int Yaz_Proxy::send_srw_response(Z_SRW_PDU *srw_pdu)
     int ret = z_soap_codec_enc(o, &soap_package,
                               &hres->content_buf, &hres->content_len,
                               soap_handlers, 0);
+    if (m_log_mask & PROXY_LOG_REQ_CLIENT)
+    {
+       yaz_log (LOG_LOG, "%sSending %s to client", m_session_str,
+                gdu_name(gdu));
+    }
     int len;
-    return send_GDU(gdu, &len);
+    int r = send_GDU(gdu, &len);
+    logtime();
+    return r;
 }
 
 int Yaz_Proxy::send_to_srw_client_error(int srw_error)
@@ -774,31 +804,20 @@ int Yaz_Proxy::send_srw_explain()
     Z_SRW_PDU *res = yaz_srw_get(odr_encode(), Z_SRW_explain_response);
     Z_SRW_explainResponse *er = res->u.explain_response;
     
-    if (m_zeerex_fname)
+    Yaz_ProxyConfig *cfg = check_reconfigure();
+    if (cfg)
     {
-       FILE *inf = fopen(m_zeerex_fname, "rb");
-       if (inf)
+       int len;
+       assert (m_proxyTarget);
+       char *b = cfg->get_explain(odr_encode(), 0 /* target */,
+                                  0 /* db */, &len);
+       if (b)
        {
-           fseek(inf, 0L, SEEK_END);
-           long sz = ftell(inf);
-           fseek(inf, 0L, SEEK_SET);
-           if (sz > 0)
-           {
-               er->record.recordData_buf = 
-                   (char*) odr_malloc(odr_encode(), sz);
-               size_t s = fread(er->record.recordData_buf, 1,sz, inf);
-               if (s > 0)
-                   er->record.recordData_len = s;
-           }
-           else
-               yaz_log(LOG_WARN|LOG_ERRNO, "zeerex file: ftell");
-           fclose(inf);
+           er->record.recordData_buf = b;
+           er->record.recordData_len = len;
+           er->record.recordPacking = m_s2z_packing;
        }
-       else
-           yaz_log(LOG_WARN|LOG_ERRNO, "zeerex file: fopen");
     }
-    else
-       yaz_log(LOG_LOG, "zeerex file: not defined");
     return send_srw_response(res);
 }
 
@@ -851,7 +870,14 @@ int Yaz_Proxy::send_PDU_convert(Z_APDU *apdu, int *len)
        }
     }
     else
-       return send_Z_PDU(apdu, len);
+    {
+       if (m_log_mask & PROXY_LOG_REQ_CLIENT)
+           yaz_log (LOG_LOG, "%sSending %s to client", m_session_str,
+                    apdu_name(apdu));
+       int r = send_Z_PDU(apdu, len);
+       logtime();
+       return r;
+    }
     return 0;
 }
 
@@ -912,9 +938,6 @@ int Yaz_Proxy::send_to_client(Z_APDU *apdu)
     int r = send_PDU_convert(apdu, &len);
     if (r)
        return r;
-    if (m_log_mask & PROXY_LOG_APDU_CLIENT)
-       yaz_log (LOG_DEBUG, "%sSending %s to client %d bytes", m_session_str,
-                apdu_name(apdu), len);
     m_bytes_sent += len;
     m_bw_stat.add_bytes(len);
     if (kill_session)
@@ -1178,12 +1201,17 @@ Z_APDU *Yaz_Proxy::result_set_optimize(Z_APDU *apdu)
 }
 
 
-void Yaz_Proxy::recv_GDU(Z_GDU *apdu, int len)
+void Yaz_Proxy::inc_request_no()
 {
     char *cp = strchr(m_session_str, ' ');
     m_request_no++;
     if (cp)
        sprintf(cp+1, "%d ", m_request_no);
+}
+
+void Yaz_Proxy::recv_GDU(Z_GDU *apdu, int len)
+{
+    inc_request_no();
 
     m_bytes_recv += len;
     
@@ -1197,6 +1225,8 @@ void Yaz_Proxy::recv_GDU(Z_GDU *apdu, int len)
     m_bw_stat.add_bytes(len);
     m_pdu_stat.add_bytes(1);
 
+    gettimeofday(&m_time_tv, 0);
+
     int bw_total = m_bw_stat.get_total();
     int pdu_total = m_pdu_stat.get_total();
 
@@ -1568,6 +1598,14 @@ void Yaz_Proxy::handle_incoming_HTTP(Z_HTTP_Request *hreq)
        }
        else if (srw_pdu->which == Z_SRW_explain_request)
        {
+           Z_SRW_explainRequest *srw_req = srw_pdu->u.explain_request;
+           
+           if (srw_req->recordPacking &&
+               !strcmp(srw_req->recordPacking, "xml"))
+               m_s2z_packing = Z_SRW_recordPacking_XML;
+           else
+               m_s2z_packing = Z_SRW_recordPacking_string;
+
            if (!m_client)
            {
                yaz_log(LOG_LOG, "handle_incoming: initRequest");
@@ -1754,6 +1792,7 @@ void Yaz_ProxyClient::shutdown()
 
 void Yaz_Proxy::failNotify()
 {
+    inc_request_no();
     yaz_log (LOG_LOG, "%sConnection closed by client",
             get_session_str());
     shutdown();
@@ -1761,6 +1800,8 @@ void Yaz_Proxy::failNotify()
 
 void Yaz_ProxyClient::failNotify()
 {
+    if (m_server)
+       m_server->inc_request_no();
     yaz_log (LOG_LOG, "%sConnection closed by target %s", 
             get_session_str(), get_hostname());
     shutdown();
@@ -1854,8 +1895,7 @@ void Yaz_Proxy::pre_init()
                                          &keepalive_limit_bw,
                                          &keepalive_limit_pdu,
                                          &pre_init,
-                                         &cql2rpn,
-                                         &zeerex) ; i++)
+                                         &cql2rpn) ; i++)
     {
        if (pre_init)
        {
@@ -1931,6 +1971,8 @@ void Yaz_Proxy::timeoutNotify()
        }
        else
        {
+           inc_request_no();
+
            yaz_log (LOG_LOG, "%sTimeout (client to proxy)", m_session_str);
            shutdown();
        }
@@ -1944,6 +1986,9 @@ void Yaz_Proxy::timeoutNotify()
 
 void Yaz_ProxyClient::timeoutNotify()
 {
+    if (m_server)
+       m_server->inc_request_no();
+
     yaz_log (LOG_LOG, "%sTimeout (proxy to target) %s", get_session_str(),
             get_hostname());
     m_waiting = 1;