SQLiteLogDb.cpp
Go to the documentation of this file.
00001 // this is for emacs file handling -*- mode: c++; indent-tabs-mode: nil -*-
00002 
00003 // -- BEGIN LICENSE BLOCK ----------------------------------------------
00004 // This file is part of FZIs ic_workspace.
00005 //
00006 // This program is free software licensed under the LGPL
00007 // (GNU LESSER GENERAL PUBLIC LICENSE Version 3).
00008 // You can find a copy of this license in LICENSE folder in the top
00009 // directory of the source code.
00010 //
00011 // © Copyright 2016 FZI Forschungszentrum Informatik, Karlsruhe, Germany
00012 //
00013 // -- END LICENSE BLOCK ------------------------------------------------
00014 
00015 //----------------------------------------------------------------------
00022 //----------------------------------------------------------------------
00023 #include "SQLiteLogDb.h"
00024 
00025 #include <iostream>
00026 
00027 namespace icl_core {
00028 namespace logging {
00029 
00030 icl_core::String SQLiteLogDb::m_create_sql =
00031   "CREATE TABLE log_entries (seq INTEGER PRIMARY KEY, app_id TEXT, "
00032   "timestamp TIMESTAMP, log_stream TEXT, log_level TEXT, filename TEXT, "
00033   "line INTEGER, class_name TEXT, object_name TEXT, function_name TEXT, message TEXT)";
00034 icl_core::String SQLiteLogDb::m_insert_sql =
00035   "INSERT INTO log_entries (app_id, timestamp, log_stream, log_level, "
00036   "filename, line, class_name, object_name, function_name, message) "
00037   "VALUES (:app_id, :timestamp, :log_stream, :log_level, :filename, "
00038   ":line, :class_name, :object_name, :function_name, :message)";
00039 
00040 SQLiteLogDb::SQLiteLogDb(const icl_core::String& db_filename, bool rotate)
00041   : m_db_filename(db_filename),
00042     m_db(NULL),
00043     m_insert_stmt(NULL),
00044     m_rotate(rotate),
00045     m_last_rotation(icl_core::TimeStamp::now().days())
00046 {
00047 }
00048 
00049 SQLiteLogDb::~SQLiteLogDb()
00050 {
00051   closeDatabase();
00052 }
00053 
00054 void SQLiteLogDb::openDatabase()
00055 {
00056   char *error = NULL;
00057 
00058   if (m_db_filename != "")
00059   {
00060     int res = SQLITE_OK;
00061     sqlite3_stmt *query_sql = NULL;
00062 
00063     // Try to open the database.
00064     res = sqlite3_open(m_db_filename.c_str(), &m_db);
00065     if (res != SQLITE_OK)
00066     {
00067       std::cerr << "SQLite log output: Could not open SQLite database "
00068                 << m_db_filename << ": " << sqlite3_errmsg(m_db) << std::endl;
00069       goto fail_return;
00070     }
00071 
00072     res = sqlite3_prepare_v2(m_db,
00073                              "SELECT sql FROM sqlite_master WHERE type='table' AND name='log_entries'",
00074                              -1, &query_sql, NULL);
00075     if (res != SQLITE_OK)
00076     {
00077       std::cerr << "SQLite log output: Could not check if the log table exists in "
00078                 << m_db_filename << ": " << sqlite3_errmsg(m_db) << std::endl;
00079       goto fail_return;
00080     }
00081 
00082     res = sqlite3_step(query_sql);
00083     if (res == SQLITE_DONE)
00084     {
00085       if (sqlite3_exec(m_db, m_create_sql.c_str(), NULL, NULL, &error) != SQLITE_OK)
00086       {
00087         std::cerr << "SQLite log output: Could not create the log table: " << error << std::endl;
00088         sqlite3_free(error);
00089         sqlite3_finalize(query_sql);
00090         goto fail_return;
00091       }
00092     }
00093 
00094     sqlite3_finalize(query_sql);
00095 
00096     // If we reach this point then the database is ready for action,
00097     // so we prepare the insert statement.
00098     res = sqlite3_prepare_v2(m_db, m_insert_sql.c_str(), -1, &m_insert_stmt, NULL);
00099     if (res != SQLITE_OK)
00100     {
00101       std::cerr << "SQLite log output: Could not prepare the insert statement: "
00102                 << sqlite3_errmsg(m_db) << std::endl;
00103       goto fail_return;
00104     }
00105 
00106     // Finally, we set some PRAGMAs to speed up operation.
00107     error = NULL;
00108     res = sqlite3_exec(m_db, "PRAGMA synchronous=OFF", NULL, NULL, &error);
00109     if (res != SQLITE_OK)
00110     {
00111       std::cerr << "SQLite log output: Could not set PRAGMA synchronous=OFF: " << error << std::endl;
00112     }
00113 
00114     error = NULL;
00115     res = sqlite3_exec(m_db, "PRAGMA temp_store=MEMORY", NULL, NULL, &error);
00116     if (res != SQLITE_OK)
00117     {
00118       std::cerr << "SQLite log output: Could not set PRAGMA temp_store=MEMORY: " << error << std::endl;
00119     }
00120   }
00121 
00122   return;
00123 fail_return:
00124   closeDatabase();
00125 }
00126 
00127 void SQLiteLogDb::closeDatabase()
00128 {
00129   if (m_insert_stmt != NULL)
00130   {
00131     sqlite3_finalize(m_insert_stmt);
00132     m_insert_stmt = NULL;
00133   }
00134 
00135   if (m_db != NULL)
00136   {
00137     sqlite3_close(m_db);
00138     m_db = NULL;
00139   }
00140 }
00141 
00142 void SQLiteLogDb::writeLogLine(const char *app_id, const char *timestamp, const char *log_stream,
00143                                const char *log_level, const char *filename,
00144                                size_t line, const char *class_name, const char *object_name,
00145                                const char *function_name, const char *message_text)
00146 {
00147   if (m_rotate)
00148   {
00149     int64_t current_day = icl_core::TimeStamp::now().days();
00150     if (m_last_rotation != current_day)
00151     {
00152       m_last_rotation = current_day;
00153 
00154       closeDatabase();
00155 
00156       char time_str[11];
00157       icl_core::TimeStamp::now().strfTime(time_str, 11, "%Y-%m-%d");
00158       rename(m_db_filename.c_str(), (m_db_filename + "." + time_str).c_str());
00159 
00160       openDatabase();
00161     }
00162   }
00163 
00164   if (m_db != NULL && m_insert_stmt != NULL)
00165   {
00166     int res = SQLITE_OK;
00167 
00168     // Bind the statement parameters.
00169     res = sqlite3_bind_text(m_insert_stmt, 1, app_id, -1, SQLITE_TRANSIENT);
00170     if (res != SQLITE_OK)
00171     {
00172       std::cerr << "SQLite log output: Could not bind column 'app_id': "
00173                 << sqlite3_errmsg(m_db) << std::endl;
00174     }
00175     res = sqlite3_bind_text(m_insert_stmt, 2, timestamp, -1, SQLITE_TRANSIENT);
00176     if (res != SQLITE_OK)
00177     {
00178       std::cerr << "SQLite log output: Could not bind column 'timestamp': "
00179                 << sqlite3_errmsg(m_db) << std::endl;
00180     }
00181     res = sqlite3_bind_text(m_insert_stmt, 3, log_stream, -1, SQLITE_TRANSIENT);
00182     if (res != SQLITE_OK)
00183     {
00184       std::cerr << "SQLite log output: Could not bind column 'log_stream': "
00185                 << sqlite3_errmsg(m_db) << std::endl;
00186     }
00187     res = sqlite3_bind_text(m_insert_stmt, 4, log_level, -1, SQLITE_TRANSIENT);
00188     if (res != SQLITE_OK)
00189     {
00190       std::cerr << "SQLite log output: Could not bind column 'log_level': "
00191                 << sqlite3_errmsg(m_db) << std::endl;
00192     }
00193     res = sqlite3_bind_text(m_insert_stmt, 5, filename, -1, SQLITE_TRANSIENT);
00194     if (res != SQLITE_OK)
00195     {
00196       std::cerr << "SQLite log output: Could not bind column 'filename': "
00197                 << sqlite3_errmsg(m_db) << std::endl;
00198     }
00199     res = sqlite3_bind_int(m_insert_stmt, 6, line);
00200     if (res != SQLITE_OK)
00201     {
00202       std::cerr << "SQLite log output: Could not bind column 'lin': "
00203                 << sqlite3_errmsg(m_db) << std::endl;
00204     }
00205     res = sqlite3_bind_text(m_insert_stmt, 7, class_name, -1, SQLITE_TRANSIENT);
00206     if (res != SQLITE_OK)
00207     {
00208       std::cerr << "SQLite log output: Could not bind column 'class_name': "
00209                 << sqlite3_errmsg(m_db) << std::endl;
00210     }
00211     res = sqlite3_bind_text(m_insert_stmt, 8, object_name, -1, SQLITE_TRANSIENT);
00212     if (res != SQLITE_OK)
00213     {
00214       std::cerr << "SQLite log output: Could not bind column 'object_name': "
00215                 << sqlite3_errmsg(m_db) << std::endl;
00216     }
00217     res = sqlite3_bind_text(m_insert_stmt, 9, function_name, -1, SQLITE_TRANSIENT);
00218     if (res != SQLITE_OK)
00219     {
00220       std::cerr << "SQLite log output: Could not bind column 'function_name': "
00221                 << sqlite3_errmsg(m_db) << std::endl;
00222     }
00223     res = sqlite3_bind_text(m_insert_stmt, 10, message_text, -1, SQLITE_TRANSIENT);
00224     if (res != SQLITE_OK)
00225     {
00226       std::cerr << "SQLite log output: Could not bind column 'message': "
00227                 << sqlite3_errmsg(m_db) << std::endl;
00228     }
00229 
00230     // Execute the statement.
00231     res = sqlite3_step(m_insert_stmt);
00232     if (res != SQLITE_DONE)
00233     {
00234       std::cerr << "SQLite log output: Could not insert log line: "
00235                 << sqlite3_errmsg(m_db) << std::endl;
00236     }
00237 
00238     // Reset the prepared statement.
00239     sqlite3_reset(m_insert_stmt);
00240   }
00241 }
00242 
00243 }
00244 }


fzi_icl_core
Author(s):
autogenerated on Tue Aug 8 2017 02:28:04