driver/telemetry.cc (95 lines of code) (raw):
/*
* Copyright (c) 2008, 2023, Oracle and/or its affiliates. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, version 2.0, as
* published by the Free Software Foundation.
*
* This program is also distributed with certain software (including
* but not limited to OpenSSL) that is licensed under separate terms,
* as designated in a particular file or component or in included license
* documentation. The authors of MySQL hereby grant you an
* additional permission to link the program and your derivative works
* with the separately licensed software that they have included with
* MySQL.
*
* Without limiting anything contained in the foregoing, this file,
* which is part of MySQL Connector/C++, is also subject to the
* Universal FOSS Exception, version 1.0, a copy of which can be found at
* http://oss.oracle.com/licenses/universal-foss-exception.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License, version 2.0, for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "telemetry.h"
#include <VersionInfo.h>
#include "driver.h"
#include <iostream>
#include <vector>
#include <optional>
#ifdef _WIN32
#include <windows.h>
#else
#include <pthread.h>
#endif
namespace telemetry
{
Span_ptr mk_span(
std::string name,
std::optional<trace::SpanContext> link = {}
)
{
auto tracer = trace::Provider::GetTracerProvider()->GetTracer(
"MySQL Connector/ODBC " MYODBC_STRDRIVERTYPE, MYODBC_CONN_ATTR_VER
);
trace::StartSpanOptions opts;
opts.kind = trace::SpanKind::kClient;
auto span
= link ? tracer->StartSpan(name, {}, {{*link, {}}}, opts)
: tracer->StartSpan(name, opts);
span->SetAttribute("db.system", "mysql");
return span;
}
Span_ptr
Telemetry_base<DBC>::mk_span(DBC *conn, const char*)
{
auto span = telemetry::mk_span("connection");
return span;
}
void
Telemetry_base<DBC>::set_attribs(DBC *dbc, DataSource *ds)
{
if (disabled(dbc) || !span || !ds)
return;
// NOTE: There is no possibility in ODBC for "other" transport
std::string transport = "other";
if(ds->opt_SOCKET)
{
#ifndef _WIN32
transport = "socket";
span->SetAttribute("network.type", "unix");
#else
transport = "pipe";
#endif
} else {
transport = "tcp";
span->SetAttribute("network.type", "ipv4");
}
span->SetAttribute("network.transport", transport);
if (ds->opt_SERVER.is_set())
{
span->SetAttribute("server.address", (const char*)ds->opt_SERVER);
}
if (ds->opt_PORT.is_set())
{
span->SetAttribute("server.port", ds->opt_PORT);
}
}
template<>
bool
Telemetry_base<STMT>::disabled(STMT *stmt) const
{
return stmt->conn_telemetry().disabled(stmt->dbc);
}
/*
Creating statement span: we link it to the connection span and we also
set "traceparent" attribute unless user already set it.
*/
template<>
Span_ptr
Telemetry_base<STMT>::mk_span(STMT *stmt, const char* name)
{
Span_ptr local_span;
/*
If `name` is not given then this span corresponds to a plain
(not prepared) statement. Otherwise this is a span for prepared statement
prepare or execute operation and the name should indicate which operation
it is.
*/
if (!name)
name = "SQL statement";
local_span = telemetry::mk_span(name,
stmt->conn_telemetry().span->GetContext()
);
// Add "treaceparent" attribute if not already set by user.
if (!stmt->query_attr_exists("traceparent"))
{
char buf[trace::TraceId::kSize * 2];
auto ctx = local_span->GetContext();
ctx.trace_id().ToLowerBase16(buf);
std::string trace_id{buf, sizeof(buf)};
ctx.span_id().ToLowerBase16({buf, trace::SpanId::kSize * 2});
std::string span_id{buf, trace::SpanId::kSize * 2};
stmt->add_query_attr(
"traceparent", "00-" + trace_id + "-" + span_id + "-00"
);
}
local_span->SetAttribute("db.user", (const char*)stmt->dbc->ds->opt_UID);
return local_span;
}
}