00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
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
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
00097
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
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
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
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
00239 sqlite3_reset(m_insert_stmt);
00240 }
00241 }
00242
00243 }
00244 }