/**
* collectd - src/oracle.c
- * Copyright (C) 2008,2009 Florian octo Forster
+ * Copyright (C) 2008,2009 noris network AG
+ * Copyright (C) 2012 Florian octo Forster
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* affiliates. Other names may be trademarks of their respective owners.
*
* Authors:
- * Florian octo Forster <octo at noris.net>
+ * Florian octo Forster <octo at collectd.org>
**/
#include "collectd.h"
struct o_database_s
{
char *name;
+ char *host;
char *connect_id;
char *username;
char *password;
* Functions
*/
static void o_report_error (const char *where, /* {{{ */
+ const char *db_name, const char *query_name,
const char *what, OCIError *eh)
{
char buffer[2048];
sb4 error_code;
int status;
+ unsigned int record_number;
- status = OCIErrorGet (eh, /* record number = */ 1,
- /* sqlstate = */ NULL,
- &error_code,
- (text *) &buffer[0],
- (ub4) sizeof (buffer),
- OCI_HTYPE_ERROR);
- buffer[sizeof (buffer) - 1] = 0;
+ if (db_name == NULL)
+ db_name = "(none)";
+ if (query_name == NULL)
+ query_name = "(none)";
- if (status == OCI_SUCCESS)
+ /* An operation may cause / return multiple errors. Loop until we have
+ * handled all errors available (with a fail-save limit of 16). */
+ for (record_number = 1; record_number <= 16; record_number++)
{
- size_t buffer_length;
+ memset (buffer, 0, sizeof (buffer));
+ error_code = -1;
- buffer_length = strlen (buffer);
- while ((buffer_length > 0) && (buffer[buffer_length - 1] < 32))
+ status = OCIErrorGet (eh, (ub4) record_number,
+ /* sqlstate = */ NULL,
+ &error_code,
+ (text *) &buffer[0],
+ (ub4) sizeof (buffer),
+ OCI_HTYPE_ERROR);
+ buffer[sizeof (buffer) - 1] = 0;
+
+ if (status == OCI_NO_DATA)
+ return;
+
+ if (status == OCI_SUCCESS)
{
- buffer_length--;
- buffer[buffer_length] = 0;
- }
+ size_t buffer_length;
- ERROR ("oracle plugin: %s: %s failed: %s",
- where, what, buffer);
- }
- else
- {
- ERROR ("oracle plugin: %s: %s failed. Additionally, OCIErrorGet failed with status %i.",
- where, what, status);
+ buffer_length = strlen (buffer);
+ while ((buffer_length > 0) && (buffer[buffer_length - 1] < 32))
+ {
+ buffer_length--;
+ buffer[buffer_length] = 0;
+ }
+
+ ERROR ("oracle plugin: %s (db = %s, query = %s): %s failed: %s",
+ where, db_name, query_name, what, buffer);
+ }
+ else
+ {
+ ERROR ("oracle plugin: %s (db = %s, query = %s): %s failed. "
+ "Additionally, OCIErrorGet failed with status %i.",
+ where, db_name, query_name, what, status);
+ return;
+ }
}
} /* }}} void o_report_error */
* </Plugin>
*/
-static int o_config_set_string (char **ret_string, /* {{{ */
- oconfig_item_t *ci)
-{
- char *string;
-
- if ((ci->values_num != 1)
- || (ci->values[0].type != OCONFIG_TYPE_STRING))
- {
- WARNING ("oracle plugin: The `%s' config option "
- "needs exactly one string argument.", ci->key);
- return (-1);
- }
-
- string = strdup (ci->values[0].value.string);
- if (string == NULL)
- {
- ERROR ("oracle plugin: strdup failed.");
- return (-1);
- }
-
- if (*ret_string != NULL)
- free (*ret_string);
- *ret_string = string;
-
- return (0);
-} /* }}} int o_config_set_string */
-
static int o_config_add_database (oconfig_item_t *ci) /* {{{ */
{
o_database_t *db;
return (-1);
}
memset (db, 0, sizeof (*db));
+ db->name = NULL;
+ db->host = NULL;
+ db->connect_id = NULL;
+ db->username = NULL;
+ db->password = NULL;
- status = o_config_set_string (&db->name, ci);
+ status = cf_util_get_string (ci, &db->name);
if (status != 0)
{
sfree (db);
oconfig_item_t *child = ci->children + i;
if (strcasecmp ("ConnectID", child->key) == 0)
- status = o_config_set_string (&db->connect_id, child);
+ status = cf_util_get_string (child, &db->connect_id);
+ else if (strcasecmp ("Host", child->key) == 0)
+ status = cf_util_get_string (child, &db->host);
else if (strcasecmp ("Username", child->key) == 0)
- status = o_config_set_string (&db->username, child);
+ status = cf_util_get_string (child, &db->username);
else if (strcasecmp ("Password", child->key) == 0)
- status = o_config_set_string (&db->password, child);
+ status = cf_util_get_string (child, &db->password);
else if (strcasecmp ("Query", child->key) == 0)
status = udb_query_pick_from_list (child, queries, queries_num,
&db->queries, &db->queries_num);
oconfig_item_t *child = ci->children + i;
if (strcasecmp ("Query", child->key) == 0)
udb_query_create (&queries, &queries_num, child,
- /* callback = */ NULL, /* legacy mode = */ 0);
+ /* callback = */ NULL);
else if (strcasecmp ("Database", child->key) == 0)
o_config_add_database (child);
else
OCI_HTYPE_STMT, /* user_data_size = */ 0, /* user_data = */ NULL);
if (status != OCI_SUCCESS)
{
- o_report_error ("o_read_database_query", "OCIHandleAlloc", oci_error);
+ o_report_error ("o_read_database_query", db->name,
+ udb_query_get_name (q), "OCIHandleAlloc", oci_error);
oci_statement = NULL;
return (-1);
}
/* mode = */ OCI_DEFAULT);
if (status != OCI_SUCCESS)
{
- o_report_error ("o_read_database_query", "OCIStmtPrepare", oci_error);
+ o_report_error ("o_read_database_query", db->name,
+ udb_query_get_name (q), "OCIStmtPrepare", oci_error);
OCIHandleFree (oci_statement, OCI_HTYPE_STMT);
oci_statement = NULL;
return (-1);
/* mode = */ OCI_DEFAULT);
if (status != OCI_SUCCESS)
{
- DEBUG ("oracle plugin: o_read_database_query: status = %i (%#x)", status, status);
- o_report_error ("o_read_database_query", "OCIStmtExecute", oci_error);
- ERROR ("oracle plugin: o_read_database_query: "
- "Failing statement was: %s", udb_query_get_statement (q));
+ o_report_error ("o_read_database_query", db->name, udb_query_get_name (q),
+ "OCIStmtExecute", oci_error);
return (-1);
} /* }}} */
OCI_ATTR_PARAM_COUNT, oci_error);
if (status != OCI_SUCCESS)
{
- o_report_error ("o_read_database_query", "OCIAttrGet", oci_error);
+ o_report_error ("o_read_database_query", db->name,
+ udb_query_get_name (q), "OCIAttrGet", oci_error);
return (-1);
} /* }}} */
if (status != OCI_SUCCESS)
{
/* This is probably alright */
- DEBUG ("oracle plugin: o_read_database_query: status = %#x (= %i);", status, status);
- o_report_error ("o_read_database_query", "OCIParamGet", oci_error);
+ DEBUG ("oracle plugin: o_read_database_query: status = %#x (= %i);",
+ status, status);
+ o_report_error ("o_read_database_query", db->name,
+ udb_query_get_name (q), "OCIParamGet", oci_error);
status = OCI_SUCCESS;
break;
}
&column_name, &column_name_length, OCI_ATTR_NAME, oci_error);
if (status != OCI_SUCCESS)
{
- o_report_error ("o_read_database_query", "OCIAttrGet (OCI_ATTR_NAME)",
- oci_error);
+ OCIDescriptorFree (oci_param, OCI_DTYPE_PARAM);
+ o_report_error ("o_read_database_query", db->name,
+ udb_query_get_name (q), "OCIAttrGet (OCI_ATTR_NAME)", oci_error);
continue;
}
+ OCIDescriptorFree (oci_param, OCI_DTYPE_PARAM);
+ oci_param = NULL;
+
/* Copy the name to column_names. Warning: The ``string'' returned by OCI
* may not be null terminated! */
memset (column_names[i], 0, DATA_MAX_NAME_LEN);
NULL, NULL, NULL, OCI_DEFAULT);
if (status != OCI_SUCCESS)
{
- o_report_error ("o_read_database_query", "OCIDefineByPos", oci_error);
+ o_report_error ("o_read_database_query", db->name,
+ udb_query_get_name (q), "OCIDefineByPos", oci_error);
continue;
}
} /* for (j = 1; j <= param_counter; j++) */
/* }}} End of the ``define'' stuff. */
- status = udb_query_prepare_result (q, prep_area, hostname_g,
+ status = udb_query_prepare_result (q, prep_area,
+ (db->host != NULL) ? db->host : hostname_g,
/* plugin = */ "oracle", db->name, column_names, column_num,
- /* interval = */ -1);
+ /* interval = */ 0);
if (status != 0)
{
ERROR ("oracle plugin: o_read_database_query (%s, %s): "
}
else if ((status != OCI_SUCCESS) && (status != OCI_SUCCESS_WITH_INFO))
{
- o_report_error ("o_read_database_query", "OCIStmtFetch2", oci_error);
+ o_report_error ("o_read_database_query", db->name,
+ udb_query_get_name (q), "OCIStmtFetch2", oci_error);
break;
}
OCI_ATTR_SERVER, oci_error);
if (status != OCI_SUCCESS)
{
- o_report_error ("o_read_database", "OCIAttrGet", oci_error);
+ o_report_error ("o_read_database", db->name, NULL, "OCIAttrGet",
+ oci_error);
return (-1);
}
OCI_ATTR_SERVER_STATUS, oci_error);
if (status != OCI_SUCCESS)
{
- o_report_error ("o_read_database", "OCIAttrGet", oci_error);
+ o_report_error ("o_read_database", db->name, NULL, "OCIAttrGet",
+ oci_error);
return (-1);
}
}
(OraText *) db->username, (ub4) strlen (db->username),
(OraText *) db->password, (ub4) strlen (db->password),
(OraText *) db->connect_id, (ub4) strlen (db->connect_id));
- if (status != OCI_SUCCESS)
+ if ((status != OCI_SUCCESS) && (status != OCI_SUCCESS_WITH_INFO))
{
- o_report_error ("o_read_database", "OCILogon", oci_error);
+ char errfunc[256];
+
+ ssnprintf (errfunc, sizeof (errfunc), "OCILogon(\"%s\")", db->connect_id);
+
+ o_report_error ("o_read_database", db->name, NULL, errfunc, oci_error);
DEBUG ("oracle plugin: OCILogon (%s): db->oci_service_context = %p;",
db->connect_id, db->oci_service_context);
db->oci_service_context = NULL;
return (-1);
}
+ else if (status == OCI_SUCCESS_WITH_INFO)
+ {
+ /* TODO: Print NOTIFY message. */
+ }
assert (db->oci_service_context != NULL);
}
}
OCIHandleFree (oci_env, OCI_HTYPE_ENV);
+ oci_env = NULL;
udb_query_free (queries, queries_num);
queries = NULL;