00001
00002
00009
00010 #include "SQLiteLogDb.h"
00011
00012 #include <iostream>
00013
00014 namespace icl_core {
00015 namespace logging {
00016
00017 icl_core::String SQLiteLogDb::m_create_sql =
00018 "CREATE TABLE log_entries (seq INTEGER PRIMARY KEY, app_id TEXT, "
00019 "timestamp TIMESTAMP, log_stream TEXT, log_level TEXT, filename TEXT, "
00020 "line INTEGER, class_name TEXT, object_name TEXT, function_name TEXT, message TEXT)";
00021 icl_core::String SQLiteLogDb::m_insert_sql =
00022 "INSERT INTO log_entries (app_id, timestamp, log_stream, log_level, "
00023 "filename, line, class_name, object_name, function_name, message) "
00024 "VALUES (:app_id, :timestamp, :log_stream, :log_level, :filename, "
00025 ":line, :class_name, :object_name, :function_name, :message)";
00026
00027 SQLiteLogDb::SQLiteLogDb(const icl_core::String& db_filename, bool rotate)
00028 : m_db_filename(db_filename),
00029 m_db(NULL),
00030 m_insert_stmt(NULL),
00031 m_rotate(rotate),
00032 m_last_rotation(icl_core::TimeStamp::now().days())
00033 {
00034 }
00035
00036 SQLiteLogDb::~SQLiteLogDb()
00037 {
00038 closeDatabase();
00039 }
00040
00041 void SQLiteLogDb::openDatabase()
00042 {
00043 char *error = NULL;
00044
00045 if (m_db_filename != "")
00046 {
00047 int res = SQLITE_OK;
00048 sqlite3_stmt *query_sql = NULL;
00049
00050
00051 res = sqlite3_open(m_db_filename.c_str(), &m_db);
00052 if (res != SQLITE_OK)
00053 {
00054 std::cerr << "SQLite log output: Could not open SQLite database "
00055 << m_db_filename << ": " << sqlite3_errmsg(m_db) << std::endl;
00056 goto fail_return;
00057 }
00058
00059 res = sqlite3_prepare_v2(m_db,
00060 "SELECT sql FROM sqlite_master WHERE type='table' AND name='log_entries'",
00061 -1, &query_sql, NULL);
00062 if (res != SQLITE_OK)
00063 {
00064 std::cerr << "SQLite log output: Could not check if the log table exists in "
00065 << m_db_filename << ": " << sqlite3_errmsg(m_db) << std::endl;
00066 goto fail_return;
00067 }
00068
00069 res = sqlite3_step(query_sql);
00070 if (res == SQLITE_DONE)
00071 {
00072 if (sqlite3_exec(m_db, m_create_sql.c_str(), NULL, NULL, &error) != SQLITE_OK)
00073 {
00074 std::cerr << "SQLite log output: Could not create the log table: " << error << std::endl;
00075 sqlite3_free(error);
00076 sqlite3_finalize(query_sql);
00077 goto fail_return;
00078 }
00079 }
00080
00081 sqlite3_finalize(query_sql);
00082
00083
00084
00085 res = sqlite3_prepare_v2(m_db, m_insert_sql.c_str(), -1, &m_insert_stmt, NULL);
00086 if (res != SQLITE_OK)
00087 {
00088 std::cerr << "SQLite log output: Could not prepare the insert statement: "
00089 << sqlite3_errmsg(m_db) << std::endl;
00090 goto fail_return;
00091 }
00092
00093
00094 error = NULL;
00095 res = sqlite3_exec(m_db, "PRAGMA synchronous=OFF", NULL, NULL, &error);
00096 if (res != SQLITE_OK)
00097 {
00098 std::cerr << "SQLite log output: Could not set PRAGMA synchronous=OFF: " << error << std::endl;
00099 }
00100
00101 error = NULL;
00102 res = sqlite3_exec(m_db, "PRAGMA temp_store=MEMORY", NULL, NULL, &error);
00103 if (res != SQLITE_OK)
00104 {
00105 std::cerr << "SQLite log output: Could not set PRAGMA temp_store=MEMORY: " << error << std::endl;
00106 }
00107 }
00108
00109 return;
00110 fail_return:
00111 closeDatabase();
00112 }
00113
00114 void SQLiteLogDb::closeDatabase()
00115 {
00116 if (m_insert_stmt != NULL)
00117 {
00118 sqlite3_finalize(m_insert_stmt);
00119 m_insert_stmt = NULL;
00120 }
00121
00122 if (m_db != NULL)
00123 {
00124 sqlite3_close(m_db);
00125 m_db = NULL;
00126 }
00127 }
00128
00129 void SQLiteLogDb::writeLogLine(const char *app_id, const char *timestamp, const char *log_stream,
00130 const char *log_level, const char *filename,
00131 size_t line, const char *class_name, const char *object_name,
00132 const char *function_name, const char *message_text)
00133 {
00134 if (m_rotate)
00135 {
00136 int64_t current_day = icl_core::TimeStamp::now().days();
00137 if (m_last_rotation != current_day)
00138 {
00139 m_last_rotation = current_day;
00140
00141 closeDatabase();
00142
00143 char time_str[11];
00144 icl_core::TimeStamp::now().strfTime(time_str, 11, "%Y-%m-%d");
00145 rename(m_db_filename.c_str(), (m_db_filename + "." + time_str).c_str());
00146
00147 openDatabase();
00148 }
00149 }
00150
00151 if (m_db != NULL && m_insert_stmt != NULL)
00152 {
00153 int res = SQLITE_OK;
00154
00155
00156 res = sqlite3_bind_text(m_insert_stmt, 1, app_id, -1, SQLITE_TRANSIENT);
00157 if (res != SQLITE_OK)
00158 {
00159 std::cerr << "SQLite log output: Could not bind column 'app_id': "
00160 << sqlite3_errmsg(m_db) << std::endl;
00161 }
00162 res = sqlite3_bind_text(m_insert_stmt, 2, timestamp, -1, SQLITE_TRANSIENT);
00163 if (res != SQLITE_OK)
00164 {
00165 std::cerr << "SQLite log output: Could not bind column 'timestamp': "
00166 << sqlite3_errmsg(m_db) << std::endl;
00167 }
00168 res = sqlite3_bind_text(m_insert_stmt, 3, log_stream, -1, SQLITE_TRANSIENT);
00169 if (res != SQLITE_OK)
00170 {
00171 std::cerr << "SQLite log output: Could not bind column 'log_stream': "
00172 << sqlite3_errmsg(m_db) << std::endl;
00173 }
00174 res = sqlite3_bind_text(m_insert_stmt, 4, log_level, -1, SQLITE_TRANSIENT);
00175 if (res != SQLITE_OK)
00176 {
00177 std::cerr << "SQLite log output: Could not bind column 'log_level': "
00178 << sqlite3_errmsg(m_db) << std::endl;
00179 }
00180 res = sqlite3_bind_text(m_insert_stmt, 5, filename, -1, SQLITE_TRANSIENT);
00181 if (res != SQLITE_OK)
00182 {
00183 std::cerr << "SQLite log output: Could not bind column 'filename': "
00184 << sqlite3_errmsg(m_db) << std::endl;
00185 }
00186 res = sqlite3_bind_int(m_insert_stmt, 6, line);
00187 if (res != SQLITE_OK)
00188 {
00189 std::cerr << "SQLite log output: Could not bind column 'lin': "
00190 << sqlite3_errmsg(m_db) << std::endl;
00191 }
00192 res = sqlite3_bind_text(m_insert_stmt, 7, class_name, -1, SQLITE_TRANSIENT);
00193 if (res != SQLITE_OK)
00194 {
00195 std::cerr << "SQLite log output: Could not bind column 'class_name': "
00196 << sqlite3_errmsg(m_db) << std::endl;
00197 }
00198 res = sqlite3_bind_text(m_insert_stmt, 8, object_name, -1, SQLITE_TRANSIENT);
00199 if (res != SQLITE_OK)
00200 {
00201 std::cerr << "SQLite log output: Could not bind column 'object_name': "
00202 << sqlite3_errmsg(m_db) << std::endl;
00203 }
00204 res = sqlite3_bind_text(m_insert_stmt, 9, function_name, -1, SQLITE_TRANSIENT);
00205 if (res != SQLITE_OK)
00206 {
00207 std::cerr << "SQLite log output: Could not bind column 'function_name': "
00208 << sqlite3_errmsg(m_db) << std::endl;
00209 }
00210 res = sqlite3_bind_text(m_insert_stmt, 10, message_text, -1, SQLITE_TRANSIENT);
00211 if (res != SQLITE_OK)
00212 {
00213 std::cerr << "SQLite log output: Could not bind column 'message': "
00214 << sqlite3_errmsg(m_db) << std::endl;
00215 }
00216
00217
00218 res = sqlite3_step(m_insert_stmt);
00219 if (res != SQLITE_DONE)
00220 {
00221 std::cerr << "SQLite log output: Could not insert log line: "
00222 << sqlite3_errmsg(m_db) << std::endl;
00223 }
00224
00225
00226 sqlite3_reset(m_insert_stmt);
00227 }
00228 }
00229
00230 }
00231 }