diff --git a/content/guides/integrations/sql/java_sql.md b/content/guides/integrations/sql/java_sql.md index b96bb4b0..11c829bc 100644 --- a/content/guides/integrations/sql/java_sql.md +++ b/content/guides/integrations/sql/java_sql.md @@ -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 --- @@ -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 @@ -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 } @@ -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 @@ -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); + } } {{}} {{}} @@ -396,14 +417,15 @@ 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, @@ -411,7 +433,7 @@ you should be able to see such visuals // 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)