Skip to content
This repository has been archived by the owner on Oct 3, 2023. It is now read-only.

Commit

Permalink
integrations/sql: retouch ocjdbc to ensure working end-to-end
Browse files Browse the repository at this point in the history
Retouch the OCJDBC integration guide now that it was successfully
published on Sonatype. This retouch ensures that the end-to-end
example fully compiles. The last edits of the actual integration
introduced an unexpected compulsory option which rendered the
previous guide uncompilable.

This change also involved running `./gradlew goJF` to format
the Java source code.

Updates #527
  • Loading branch information
odeke-em committed Jan 12, 2019
1 parent cd19969 commit 7f20f1a
Showing 1 changed file with 107 additions and 85 deletions.
192 changes: 107 additions & 85 deletions content/guides/integrations/sql/java_sql.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
title: "Java"
date: 2018-09-25T00:25:42-07:00
draft: false
aliases: [/integrations/sql/java]
aliases: [/integrations/sql/java, /guides/integrations/sql/ocjdbc, /guides/integrations/sql/jdbc]
logo: /img/sql-java.png
---

Expand All @@ -22,13 +22,13 @@ The Java Database Connectivity(JDBC) API provides universal data access from the
documented at https://docs.oracle.com/javase/8/docs/technotes/guides/jdbc/

Using OpenCensus, we've combined the best of both worlds: observability with distributed tracing and metrics
to empower Java developers that use any sort of a database/data source with a JDBC driver.
to empower Java developers that use any sort of database/data source with a [JDBC](https://docs.oracle.com/javase/8/docs/technotes/guides/jdbc/) driver.

ocjdbc is a type-4 JDBC wrapper for the Java language. We've instrumented it with OpenCensus to provide
observability with tracing and metrics. It works by wrapping your already obtained JDBC Connection using
the class `ocjdbc.Connection`. It wraps any JDBC driver. It is hosted on our integrations page on
the class `ocjdbc.OcWrapConnection`. It wraps any JDBC driver. It is hosted on our integrations page on
Github at https://github.com/opencensus-integrations/ocjdbc
but also distributed as a Maven artifact as you'll shortly see below.
but also distributed as Maven, Gradle, Ivy and Builder artifacts as you'll shortly see below.

## Installing it

Expand Down Expand Up @@ -61,17 +61,20 @@ compile group: 'io.orijtech.integrations', name: 'ocjdbc', version: '0.0.2'
Using it simply requires you to just wrap your already created JDBC connection and it wraps every method
to provide observability by metrics and tracing. For example
```java
import io.orijtech.integrations.ocjdbc.Connection;
import io.orijtech.integrations.ocjdbc.OcWrapConnection;
import io.orijtech.integrations.ocjdbc.Observability;

public static void main(String ...args) {
// Load and use the MySQL Connector/J driver.
Class.forName("com.mysql.cj.jdbc.Driver").newInstance();

java.sql.Connection originalConn = java.sql.DriverManager.getConnection("jdbc:mysql://localhost/test?useSSL=false&serverTimezone=UTC");
java.sql.Connection originalConn =
java.sql.DriverManager.getConnection(
"jdbc:mysql://localhost/test?useSSL=false&serverTimezone=UTC");

// Then create/wrap it with the instrumented Connection from "io.orijtech.integrations.ocjdbc".
java.sql.Connection conn = new Connection(originalConn);
java.sql.Connection conn =
new OcWrapConnection(originalConn, EnumSet.of(Observability.TraceOption.NONE));

// Use conn like you would normally below as per your original program
}
Expand All @@ -92,20 +95,23 @@ We also provide an option for your spans to be annotated with the SQL that accom
However, please note that this is optional and could be a security concern due to Personally Identifiable Information(PII)
being used in the SQL query.

This option is available via `Observability.OPTION_ANNOTATE_TRACES_WITH_SQL` which is passed into the constructors for:
* Connection
* CallableStatement
* PreparedStatement
* Statement
This option is available via `TraceOption` of `Observability.ANNOTATE_TRACES_WITH_SQL` which is passed into the constructors for:
* OcWrapConnection
* OcWrapCallableStatement
* OcWrapPreparedStatement
* OcWrapStatement

thus when used to create the wrapped `java.sql.Connection`:
```java
java.sql.Connection conn = new Connection(originalConn,
// And passing this option to allow the spans
// to be annotated with the SQL queries.
// Please note that this could be a security concern
// since it could reveal personally identifying information.
Observability.OPTION_ANNOTATE_TRACES_WITH_SQL);
java.sql.Connection conn =
new OcWrapConnection(
originalConn,
// And passing this option to allow the spans
// to be annotated with the SQL queries.
// Please note that this could be a security concern
// since it could reveal personally identifying information.
EnumSet.of(Observability.TraceOption.ANNOTATE_TRACES_WITH_SQL));

```

## Enabling OpenCensus
Expand Down Expand Up @@ -154,85 +160,100 @@ In this example, we'll just wrap a MySQL Connector/J app as below. Please place
// Please place the file in: src/main/java/io/opencensus/tutorial/ocjdbc/App.java
package io.opencensus.tutorial.ocjdbc;

import io.orijtech.integrations.ocjdbc.Connection;
import io.orijtech.integrations.ocjdbc.Observability;

import io.opencensus.exporter.trace.jaeger.JaegerTraceExporter;
import io.opencensus.exporter.stats.prometheus.PrometheusStatsCollector;
import io.prometheus.client.exporter.HTTPServer;
import io.opencensus.trace.samplers.Samplers;
import io.opencensus.common.Scope;
import io.opencensus.exporter.stats.prometheus.PrometheusStatsCollector;
import io.opencensus.exporter.trace.jaeger.JaegerTraceExporter;
import io.opencensus.trace.Tracer;
import io.opencensus.trace.Tracing;
import io.opencensus.trace.config.TraceConfig;
import io.opencensus.trace.samplers.Samplers;
import io.orijtech.integrations.ocjdbc.Observability;
import io.orijtech.integrations.ocjdbc.OcWrapConnection;
import io.prometheus.client.exporter.HTTPServer;
import java.util.EnumSet;

public class App {
private static final Tracer tracer = Tracing.getTracer();

public static void main(String ...args) {
private static final Tracer tracer = Tracing.getTracer();

public static void main(String... args) {
java.sql.Connection conn = null;

try {
enableObservability();

// Load and use the MySQL Connector/J driver.
Class.forName("com.mysql.cj.jdbc.Driver").newInstance();

java.sql.Connection originalConn =
java.sql.DriverManager.getConnection(
"jdbc:mysql://localhost/repro?user=root&useSSL=false&serverTimezone=UTC");
/*
Optionally enable annotation of spans with the accompanying SQL statements.
java.sql.Connection conn = new OcWrapConnection(originalConn,
// And passing this option to allow the spans
// to be annotated with the SQL queries.
// Please note that this could be a security concern
// since it could reveal personally identifying information.
EnumSet.of(Observability.TraceOption.ANNOTATE_TRACES_WITH_SQL));
*/

// Then create/wrap it with the instrumented Connection from
// "io.orijtech.integrations.ocjdbc".
conn = new OcWrapConnection(originalConn, EnumSet.of(Observability.TraceOption.NONE));
doWork(conn);
} catch (Exception e) {
e.printStackTrace();
System.err.println(String.format("Failed to create SQLDriver: %s", e));
return;
} finally {
// Finally close the connection when done.
if (conn != null) {
try {
enableObservability();

// Load and use the MySQL Connector/J driver.
Class.forName("com.mysql.cj.jdbc.Driver").newInstance();

java.sql.Connection originalConn = java.sql.DriverManager.getConnection("jdbc:mysql://localhost/repro?user=root&useSSL=false&serverTimezone=UTC");
/*
Optionally enable annotation of spans with the accompanying SQL statements.
java.sql.Connection conn = new Connection(originalConn,
// And passing this option to allow the spans
// to be annotated with the SQL queries.
// Please note that this could be a security concern
// since it could reveal personally identifying information.
Observability.OPTION_ANNOTATE_TRACES_WITH_SQL);
*/

// Then create/wrap it with the instrumented Connection from "io.orijtech.integrations.ocjdbc".
java.sql.Connection conn = new Connection(originalConn);
doWork(conn);
conn.close();
} catch (Exception e) {
e.printStackTrace();
System.err.println(String.format("Failed to create SQLDriver: %s", e));
return;
e.printStackTrace();
System.err.println(String.format("Failed to close conn: %s", e));
}
}
}

public static void doWork(java.sql.Connection conn) throws Exception {
System.out.println("Hello OCJDBC!");

for (int i = 0; i < 200; i++) {
Scope ss = tracer.spanBuilder(String.format("DoWork-%d", i)).startScopedSpan();
try {
java.sql.Statement stmt = conn.createStatement();
java.sql.ResultSet rs = stmt.executeQuery("SELECT * from repro");
rs.close();
System.out.println("Iteration #" + i);
} finally {
ss.close();
}

Thread.sleep(4000);
}
}

public static void doWork(java.sql.Connection conn) throws Exception {
System.out.println("Hello OCJDBC!");

for (int i = 0; i < 200; i++) {
Scope ss = tracer.spanBuilder(String.format("DoWork-%d", i)).startScopedSpan();
try {
java.sql.Statement stmt = conn.createStatement();
java.sql.ResultSet rs = stmt.executeQuery("SELECT * from repro");
rs.close();
System.out.println("Iteration #" + i);
} finally {
ss.close();
}

Thread.sleep(4000);
}
}

public static void enableObservability() throws Exception {
// Enable metrics with OpenCensus.
Observability.registerAllViews();
public static void enableObservability() throws Exception {
// Enable metrics with OpenCensus.
Observability.registerAllViews();

TraceConfig traceConfig = Tracing.getTraceConfig();
// For demo purposes, lets always sample.
traceConfig.updateActiveTraceParams(
traceConfig.getActiveTraceParams().toBuilder().setSampler(Samplers.alwaysSample()).build());
TraceConfig traceConfig = Tracing.getTraceConfig();
// For demo purposes, lets always sample.
traceConfig.updateActiveTraceParams(
traceConfig.getActiveTraceParams().toBuilder().setSampler(Samplers.alwaysSample()).build());

// The trace exporter.
JaegerTraceExporter.createAndRegister("http://127.0.0.1:14268/api/traces", "ocjdbc-demo");
// The trace exporter.
JaegerTraceExporter.createAndRegister("http://127.0.0.1:14268/api/traces", "ocjdbc-demo");

// The metrics exporter.
PrometheusStatsCollector.createAndRegister();
// The metrics exporter.
PrometheusStatsCollector.createAndRegister();

// Run the server as a daeon on address "localhost:8889".
HTTPServer server = new HTTPServer("localhost", 8889);
}
// Run the server as a daeon on address "localhost:8889".
HTTPServer server = new HTTPServer("localhost", 8889);
}
}
{{</highlight>}}
{{<highlight xml>}}
Expand Down Expand Up @@ -396,22 +417,23 @@ you should be able to see such visuals
* All traces
![](/images/ocjdbc-tracing-all.png)

* An individual trace with option `Observability.OPTION_ANNOTATE_TRACES_WITH_SQL` disabled
* An individual trace with option `Observability.ANNOTATE_TRACES_WITH_SQL` disabled
```java
// Then create/wrap it with the instrumented Connection from "io.opencensus.ocjdbc".
java.sql.Connection conn = new Connection(originalConn);
java.sql.Connection conn =
new OcWrapConnection(originalConn, EnumSet.of(Observability.TraceOption.NONE));
```
![](/images/ocjdbc-tracing-single-without-sql.png)

* An individual trace with option `Observability.OPTION_ANNOTATE_TRACES_WITH_SQL` enabled
* An individual trace with `Observability.TraceOption.ANNOTATE_TRACES_WITH_SQL` enabled

```java
java.sql.Connection conn = new Connection(originalConn,
// And passing this option to allow the spans
// to be annotated with the SQL queries.
// Please note that this could be a security concern
// since it could reveal personally identifying information.
Observability.OPTION_ANNOTATE_TRACES_WITH_SQL);
EnumSet.of(Observability.ANNOTATE_TRACES_WITH_SQL));
```
giving
![](/images/ocjdbc-tracing-single-with-sql.png)
Expand Down

0 comments on commit 7f20f1a

Please sign in to comment.