Skip to content

Commit 7334af1

Browse files
Bogdan Degtyariovrsomla1
authored andcommitted
WL#15808 - OpenTelemetry tracing - missing bits
Change-Id: I373337c04302acef3848c188a672ad02cc94b035
1 parent ddb70c4 commit 7334af1

8 files changed

+321
-119
lines changed

jdbc/driver/mysql_connection.cpp

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1495,6 +1495,10 @@ void MySQL_Connection::init(ConnectOptionsMap & properties)
14951495
el->hasPort() ? el->Port() : uri.DefaultPort(),
14961496
el->SocketOrPipe());
14971497
connected = true;
1498+
1499+
// Connected. We can set the connection telemetry.
1500+
intern->telemetry.set_attribs(this, *el);
1501+
currentUser = userName;
14981502
break;
14991503
}
15001504
catch (sql::SQLException& e)
@@ -1852,24 +1856,9 @@ MySQL_Connection::prepareStatement(const sql::SQLString& sql)
18521856
CPP_ENTER_WL(intern->logger, "MySQL_Connection::prepareStatement");
18531857
CPP_INFO_FMT("query=%s", sql.c_str());
18541858
checkClosed();
1855-
std::shared_ptr<NativeAPI::NativeStatementWrapper> stmt;
1856-
1857-
//TODO change - probably no need to catch and throw here. Logging can be done inside proxy
1858-
try {
1859-
stmt.reset(&proxy->stmt_init());
1860-
} catch (sql::SQLException& e) {
1861-
CPP_ERR_FMT("No statement : %d:(%s) %s", proxy->errNo(), proxy->sqlstate().c_str(), proxy->error().c_str());
1862-
throw e;
1863-
}
18641859

1865-
if (stmt->prepare(sql)) {
1866-
CPP_ERR_FMT("Cannot prepare %d:(%s) %s", stmt->errNo(), stmt->sqlstate().c_str(), stmt->error().c_str());
1867-
sql::SQLException e(stmt->error(), stmt->sqlstate(), stmt->errNo());
1868-
stmt.reset();
1869-
throw e;
1870-
}
1871-
1872-
return new MySQL_Prepared_Statement(stmt, this, intern->defaultPreparedStatementResultType, intern->logger);
1860+
return new MySQL_Prepared_Statement(sql, this,
1861+
intern->defaultPreparedStatementResultType, intern->logger);
18731862
}
18741863
/* }}} */
18751864

@@ -2178,6 +2167,18 @@ MySQL_Connection::getLastStatementInfo()
21782167
/* }}} */
21792168

21802169

2170+
/* {{{ MySQL_Connection::getCurrentUser() -I- */
2171+
sql::SQLString
2172+
MySQL_Connection::getCurrentUser()
2173+
{
2174+
CPP_ENTER_WL(intern->logger, "MySQL_Connection::getCurrentUser");
2175+
checkClosed();
2176+
2177+
return currentUser;
2178+
}
2179+
/* }}} */
2180+
2181+
21812182
/* {{{ MySQL_Connection::getSessionVariable() -I- */
21822183
sql::SQLString
21832184
MySQL_Connection::getSessionVariable(const sql::SQLString & varname)

jdbc/driver/mysql_connection.h

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ class CPPCONN_PUBLIC_FUNC MySQL_Savepoint : public sql::Savepoint
6767
class MySQL_DebugLogger;
6868
struct MySQL_ConnectionData; /* PIMPL */
6969
class MySQL_Statement;
70+
class MySQL_Prepared_Statement;
7071

7172
namespace NativeAPI
7273
{
@@ -76,7 +77,8 @@ class NativeConnectionWrapper;
7677
class CPPCONN_PUBLIC_FUNC MySQL_Connection : public sql::Connection
7778
{
7879
friend MySQL_Statement;
79-
80+
friend MySQL_Prepared_Statement;
81+
8082
MySQL_Statement * createServiceStmt();
8183

8284
public:
@@ -177,11 +179,13 @@ class CPPCONN_PUBLIC_FUNC MySQL_Connection : public sql::Connection
177179

178180
virtual sql::SQLString getLastStatementInfo();
179181

182+
sql::SQLString getCurrentUser();
183+
180184
private:
181185
/* We do not really think this class has to be subclassed*/
182186
void checkClosed();
183187
void init(std::map< sql::SQLString, sql::ConnectPropertyVal > & properties);
184-
188+
185189
Driver * driver;
186190

187191
#ifdef _WIN32
@@ -206,6 +210,9 @@ class CPPCONN_PUBLIC_FUNC MySQL_Connection : public sql::Connection
206210
#pragma warning(pop)
207211
#endif
208212

213+
/* We need to store the user name for telemetry */
214+
SQLString currentUser;
215+
209216
/* Prevent use of these */
210217
MySQL_Connection(const MySQL_Connection &);
211218
void operator=(MySQL_Connection &);

jdbc/driver/mysql_prepared_statement.cpp

Lines changed: 131 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include <string.h>
3333
#include <stdlib.h>
3434
#include <stdio.h>
35+
#include <assert.h>
3536

3637
#include <iostream>
3738
#include <sstream>
@@ -47,6 +48,7 @@ DIAGNOSTIC_POP
4748
#endif
4849
#include <cppconn/exception.h>
4950
#include "mysql_connection.h"
51+
#include "mysql_connection_data.h"
5052
#include "mysql_statement.h"
5153
#include "mysql_prepared_statement.h"
5254
#include "mysql_ps_resultset.h"
@@ -352,28 +354,68 @@ class MySQL_ParamBind
352354
};
353355

354356

357+
telemetry::Telemetry<MySQL_Connection>&
358+
MySQL_Prepared_Statement::conn_telemetry()
359+
{
360+
assert(connection);
361+
assert(connection->intern);
362+
return connection->intern->telemetry;
363+
}
364+
365+
355366
/* {{{ MySQL_Prepared_Statement::MySQL_Prepared_Statement() -I- */
356367
MySQL_Prepared_Statement::MySQL_Prepared_Statement(
357-
std::shared_ptr<NativeAPI::NativeStatementWrapper> &s,
368+
const sql::SQLString &sql,
358369
MySQL_Connection *conn, sql::ResultSet::enum_type rset_type,
359370
std::shared_ptr<MySQL_DebugLogger> &log)
360371
: connection(conn),
361-
proxy(s),
362372
isClosed(false),
363373
warningsHaveBeenLoaded(true),
364374
logger(log),
365375
resultset_type(rset_type),
366-
result_bind(new MySQL_ResultBind(proxy, logger)),
367376
warningsCount(0)
368377

369378
{
370379
CPP_ENTER("MySQL_Prepared_Statement::MySQL_Prepared_Statement");
371380
CPP_INFO_FMT("this=%p", this);
372-
param_count = proxy->param_count();
373-
param_bind.reset(new MySQL_ParamBind(param_count));
374381

375-
res_meta.reset(new MySQL_PreparedResultSetMetaData(proxy, logger));
376-
param_meta.reset(new MySQL_ParameterMetaData(proxy));
382+
std::shared_ptr<NativeAPI::NativeStatementWrapper> stmt;
383+
384+
//TODO change - probably no need to catch and throw here. Logging can be done inside proxy
385+
auto &connProxy = connection->proxy;
386+
try {
387+
stmt.reset(&connProxy->stmt_init());
388+
} catch (sql::SQLException& e) {
389+
CPP_ERR_FMT("No statement : %d:(%s) %s", connProxy->errNo(),
390+
connProxy->sqlstate().c_str(), connProxy->error().c_str());
391+
throw e;
392+
}
393+
394+
telemetry.span_start(this, "SQL prepare");
395+
try
396+
{
397+
if (stmt->prepare(sql)) {
398+
CPP_ERR_FMT("Cannot prepare %d:(%s) %s", stmt->errNo(), stmt->sqlstate().c_str(), stmt->error().c_str());
399+
sql::SQLException e(stmt->error(), stmt->sqlstate(), stmt->errNo());
400+
stmt.reset();
401+
throw e;
402+
}
403+
404+
proxy = stmt;
405+
result_bind.reset(new MySQL_ResultBind(proxy, logger));
406+
407+
param_count = proxy->param_count();
408+
param_bind.reset(new MySQL_ParamBind(param_count));
409+
410+
res_meta.reset(new MySQL_PreparedResultSetMetaData(proxy, logger));
411+
param_meta.reset(new MySQL_ParameterMetaData(proxy));
412+
}
413+
catch(sql::SQLException &e)
414+
{
415+
telemetry.set_error(this, e.what());
416+
throw;
417+
}
418+
telemetry.span_end(this);
377419
}
378420
/* }}} */
379421

@@ -418,20 +460,30 @@ MySQL_Prepared_Statement::sendLongDataBeforeParamBind()
418460
void
419461
MySQL_Prepared_Statement::do_query()
420462
{
421-
CPP_ENTER("MySQL_Prepared_Statement::do_query");
422-
if (param_count && !param_bind->isAllSet()) {
423-
CPP_ERR("Value not set for all parameters");
424-
throw sql::SQLException("Value not set for all parameters");
425-
}
463+
telemetry.span_start(this, "SQL execute");
426464

427-
if (proxy->bind_param(param_bind->getBindObject())) {
428-
CPP_ERR_FMT("Couldn't bind : %d:(%s) %s", proxy->errNo(), proxy->sqlstate().c_str(), proxy->error().c_str());
429-
sql::mysql::util::throwSQLException(*proxy.get());
430-
}
465+
try
466+
{
467+
CPP_ENTER("MySQL_Prepared_Statement::do_query");
468+
if (param_count && !param_bind->isAllSet()) {
469+
CPP_ERR("Value not set for all parameters");
470+
throw sql::SQLException("Value not set for all parameters");
471+
}
472+
473+
if (proxy->bind_param(param_bind->getBindObject())) {
474+
CPP_ERR_FMT("Couldn't bind : %d:(%s) %s", proxy->errNo(), proxy->sqlstate().c_str(), proxy->error().c_str());
475+
sql::mysql::util::throwSQLException(*proxy.get());
476+
}
431477

432-
if (!sendLongDataBeforeParamBind() || proxy->execute()) {
433-
CPP_ERR_FMT("Couldn't execute : %d:(%s) %s", proxy->errNo(), proxy->sqlstate().c_str(), proxy->error().c_str());
434-
sql::mysql::util::throwSQLException(*proxy.get());
478+
if (!sendLongDataBeforeParamBind() || proxy->execute()) {
479+
CPP_ERR_FMT("Couldn't execute : %d:(%s) %s", proxy->errNo(), proxy->sqlstate().c_str(), proxy->error().c_str());
480+
sql::mysql::util::throwSQLException(*proxy.get());
481+
}
482+
}
483+
catch(sql::SQLException &e)
484+
{
485+
telemetry.set_error(this, e.what());
486+
throw;
435487
}
436488

437489
warningsCount= proxy->warning_count();
@@ -473,6 +525,12 @@ MySQL_Prepared_Statement::execute()
473525
CPP_INFO_FMT("this=%p", this);
474526
checkClosed();
475527
do_query();
528+
529+
if (proxy->num_rows() == 0 && !proxy->more_results())
530+
{
531+
// No result set, just end the span
532+
telemetry.span_end(this);
533+
}
476534
return (proxy->field_count() > 0);
477535
}
478536
/* }}} */
@@ -499,23 +557,7 @@ MySQL_Prepared_Statement::executeQuery()
499557

500558
do_query();
501559

502-
my_bool bool_tmp=1;
503-
proxy->attr_set( STMT_ATTR_UPDATE_MAX_LENGTH, &bool_tmp);
504-
sql::ResultSet::enum_type tmp_type;
505-
if (resultset_type == sql::ResultSet::TYPE_SCROLL_INSENSITIVE) {
506-
if (proxy->store_result()) {
507-
sql::mysql::util::throwSQLException(*proxy.get());
508-
}
509-
tmp_type = sql::ResultSet::TYPE_SCROLL_INSENSITIVE;
510-
} else if (resultset_type == sql::ResultSet::TYPE_FORWARD_ONLY) {
511-
tmp_type = sql::ResultSet::TYPE_FORWARD_ONLY;
512-
} else {
513-
throw SQLException("Invalid value for result set type");
514-
}
515-
sql::ResultSet * tmp = new MySQL_Prepared_ResultSet(proxy, result_bind, tmp_type, this, logger);
516-
517-
CPP_INFO_FMT("rset=%p", tmp);
518-
return tmp;
560+
return _getResultSet();
519561
}
520562
/* }}} */
521563

@@ -538,6 +580,8 @@ MySQL_Prepared_Statement::executeUpdate()
538580
CPP_INFO_FMT("this=%p", this);
539581
checkClosed();
540582
do_query();
583+
// No result set, just end the span
584+
telemetry.span_end(this);
541585
return static_cast<int>(proxy->affected_rows());
542586
}
543587
/* }}} */
@@ -1017,32 +1061,50 @@ MySQL_Prepared_Statement::getParameterMetaData()
10171061
/* }}} */
10181062

10191063

1020-
/* {{{ MySQL_Prepared_Statement::getResultSet() -I- */
10211064
sql::ResultSet *
1022-
MySQL_Prepared_Statement::getResultSet()
1065+
MySQL_Prepared_Statement::_getResultSet()
10231066
{
1024-
CPP_ENTER("MySQL_Prepared_Statement::getResultSet");
1025-
CPP_INFO_FMT("this=%p", this);
1026-
checkClosed();
1027-
10281067
my_bool bool_tmp = 1;
1029-
proxy->attr_set(STMT_ATTR_UPDATE_MAX_LENGTH, &bool_tmp);
1030-
sql::ResultSet::enum_type tmp_type;
1031-
if (resultset_type == sql::ResultSet::TYPE_SCROLL_INSENSITIVE) {
1032-
if (proxy->store_result()) {
1033-
sql::mysql::util::throwSQLException(*proxy.get());
1068+
try
1069+
{
1070+
proxy->attr_set(STMT_ATTR_UPDATE_MAX_LENGTH, &bool_tmp);
1071+
sql::ResultSet::enum_type tmp_type;
1072+
if (resultset_type == sql::ResultSet::TYPE_SCROLL_INSENSITIVE) {
1073+
if (proxy->store_result()) {
1074+
sql::mysql::util::throwSQLException(*proxy.get());
1075+
}
1076+
tmp_type = sql::ResultSet::TYPE_SCROLL_INSENSITIVE;
1077+
} else if (resultset_type == sql::ResultSet::TYPE_FORWARD_ONLY) {
1078+
tmp_type = sql::ResultSet::TYPE_FORWARD_ONLY;
1079+
} else {
1080+
throw SQLException("Invalid value for result set type");
10341081
}
1035-
tmp_type = sql::ResultSet::TYPE_SCROLL_INSENSITIVE;
1036-
} else if (resultset_type == sql::ResultSet::TYPE_FORWARD_ONLY) {
1037-
tmp_type = sql::ResultSet::TYPE_FORWARD_ONLY;
1038-
} else {
1039-
throw SQLException("Invalid value for result set type");
1082+
1083+
sql::ResultSet * tmp = new MySQL_Prepared_ResultSet(proxy, result_bind, tmp_type, this, logger);
1084+
1085+
CPP_INFO_FMT("rset=%p", tmp);
1086+
return tmp;
1087+
}
1088+
catch(sql::SQLException &e)
1089+
{
1090+
telemetry.set_error(this, e.what());
1091+
throw;
10401092
}
10411093

1042-
sql::ResultSet * tmp = new MySQL_Prepared_ResultSet(proxy, result_bind, tmp_type, this, logger);
1094+
// Normally it should never come to this line.
1095+
return nullptr;
1096+
}
1097+
/* }}} */
1098+
10431099

1044-
CPP_INFO_FMT("rset=%p", tmp);
1045-
return tmp;
1100+
/* {{{ MySQL_Prepared_Statement::getResultSet() -I- */
1101+
sql::ResultSet *
1102+
MySQL_Prepared_Statement::getResultSet()
1103+
{
1104+
CPP_ENTER("MySQL_Prepared_Statement::getResultSet");
1105+
CPP_INFO_FMT("this=%p", this);
1106+
checkClosed();
1107+
return _getResultSet();
10461108
}
10471109
/* }}} */
10481110

@@ -1126,12 +1188,17 @@ MySQL_Prepared_Statement::getMoreResults()
11261188
CPP_INFO_FMT("this=%p", this);
11271189
checkClosed();
11281190

1129-
if (proxy->more_results()) {
1130-
1191+
if (proxy->more_results())
1192+
try
1193+
{
11311194
int next_result = proxy->stmt_next_result();
11321195

11331196
if (next_result == 0) {
11341197
bool ret = proxy->field_count() > 0;
1198+
if (!ret)
1199+
{
1200+
telemetry.span_end(this);
1201+
}
11351202
return ret;
11361203
} else if (next_result == -1) {
11371204
throw sql::SQLException("Impossible! more_results() said true, next_result says no more results");
@@ -1140,8 +1207,14 @@ MySQL_Prepared_Statement::getMoreResults()
11401207
sql::mysql::util::throwSQLException(*proxy.get());
11411208
}
11421209
}
1143-
return false;
1210+
catch(sql::SQLException &e)
1211+
{
1212+
telemetry.set_error(this, e.what());
1213+
throw;
1214+
}
11441215

1216+
telemetry.span_end(this);
1217+
return false;
11451218
}
11461219
/* }}} */
11471220

0 commit comments

Comments
 (0)