javasql-servermicronautjdbi

Log "print" inside stored procedure called from JDBI @SqlCall?


I'm using JBDI from a Java Micronaut application to call various stored procedures from a legacy SQL Server database application. I use the @SqlCall attribute.

For debugging purpose would be really useful to have the "print" statement inside the stored procedure logged to the Java application log.

Dbeaver is doing something similar in his output tab and I know that there is some "warning" procedure at the JBDC driver level but I don't know to use it with JDBI.


Solution

  • I have found this incomplete solution, overriding JDBI SqlLogger .

    I get only the first "print" and I'm using the ugly rSql.contains("CALL ") to find only stored procedure call.

    Probably I'm not fully understanding the internals workings of the SQL-server driver

    @Factory
    public class JdbiFactory {
        @Inject
        DataSource dataSource;
        private static final Logger LOG = LoggerFactory.getLogger(JdbiFactory.class);
    
        @Bean
        @Singleton
        public Jdbi jdbi(ResourceResolver resourceResolver) {
            return Jdbi.create(dataSource)
                .installPlugin(new SqlObjectPlugin())
                .setSqlLogger(new SqlLogger() {
                @Override
                public void logAfterExecution(StatementContext context) {
                    try {
                        var rSql = context.getRenderedSql();
                        LOG.debug("RenderedSql: [{}] ", rSql);
                        if (rSql.contains("CALL ")) {
                            // get warnings
                            final var warningSt = context.getStatement().getWarnings();
                            logThrowables(warningSt);
                            context.getStatement().clearWarnings();
                            // get warnings on results
                            do {
                                ResultSet resultSet = context.getStatement().getResultSet();
                                if (resultSet != null) {
                                    final var warningRs = resultSet.getWarnings();
                                    logThrowables(warningRs);
                                    resultSet.clearWarnings();
                                }
                            } while ( context.getStatement().getMoreResults());
                        }
                    } catch (SQLException e) {
                        LOG.error("Inside logAfterExecution error ", e);
                        e.printStackTrace();
                    }
                    SqlLogger.super.logAfterExecution(context);
                }
            });
        }
    
        private static void logThrowables(SQLException warning) {
            var iterator = warning.iterator();
            do {
                Throwable next = iterator.next();
                LOG.info("Print: [{}]", next.getMessage());
            }while(iterator.hasNext());
    
        }
    }