All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.chrisgleissner.jutil.sqllog.SqlLog Maven / Gradle / Ivy

The newest version!
package com.github.chrisgleissner.jutil.sqllog;

import lombok.Getter;
import lombok.ToString;
import lombok.extern.slf4j.Slf4j;
import net.ttddyy.dsproxy.ExecutionInfo;
import net.ttddyy.dsproxy.QueryInfo;
import net.ttddyy.dsproxy.listener.logging.DefaultJsonQueryLogEntryCreator;
import net.ttddyy.dsproxy.listener.logging.QueryLogEntryCreator;
import net.ttddyy.dsproxy.listener.logging.SLF4JLogLevel;
import net.ttddyy.dsproxy.proxy.DefaultConnectionIdManager;
import net.ttddyy.dsproxy.support.ProxyDataSourceBuilder;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;

import javax.sql.DataSource;
import java.io.OutputStream;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
import java.util.function.Predicate;
import java.util.regex.Pattern;

import static java.util.Collections.emptyList;
import static java.util.stream.Collectors.toList;

/**
 * Records SQL executions either on heap or by writing them to an OutputStream.
 *
 * 

To start recording SQL executions, use {@link #startRecording(String)} (on heap) * or {@link #startStreamRecording(String, OutputStream)} (to stream). Stop recording (and close the stream if recording to stream) * via {@link #stopRecording(String)}.

*/ @Getter @ToString @Slf4j public class SqlLog implements BeanPostProcessor { private final SqlExecutionListener sqlExecutionListener = new SqlExecutionListener(this); final QueryLogEntryCreator logEntryCreator = new DefaultJsonQueryLogEntryCreator() { protected void writeTimeEntry(StringBuilder sb, ExecutionInfo execInfo, List queryInfoList) { } }; final static InheritableThreadLocal recording = new InheritableThreadLocal<>(); private final boolean traceMethods; private boolean logQueries; SqlLog(boolean logQueries, boolean traceMethods) { this.logQueries = logQueries; this.traceMethods = traceMethods; log.debug("Created SqlLog: logQueries={}, traceMethods={}", logQueries, traceMethods); } /** * Starts a heap recording session for the specified ID. If a session with this ID is currently in progress, * it is stopped first. * * @param id under which the recordings will be tracked * @return recorded heap SQL logs for previous recording of the specified ID, empty if no such recording exists */ public Collection startRecording(String id) { return setRecording(new SqlRecording(id, null)); } /** * Starts a stream recording session for the specified ID. If a session with this ID is currently in progress, * * it is stopped first. * * @param id under which the recordings will be tracked * @return recorded heap SQL logs for previous recording of the specified ID, empty if no such recording exists */ public Collection startStreamRecording(String id, OutputStream os) { return setRecording(new SqlRecording(id, os)); } private Collection setRecording(SqlRecording newRecording) { Collection messages = getMessagesForCurrentRecording(); recording.set(newRecording); if (newRecording == null) { log.info("Stopped SQL recording"); } else log.info("Started {} recording of SQL for ID {}", newRecording.isRecordToStreamEnabled() ? "stream" : "heap", newRecording.getId()); return messages; } private Collection getMessagesForCurrentRecording() { SqlRecording oldRecording = recording.get(); Collection messages = emptyList(); if (oldRecording != null) { messages = Optional.ofNullable(sqlExecutionListener.getLogsById().remove(oldRecording.getId())).map(r -> r.getAll()).orElse(emptyList()); oldRecording.close(); } return messages; } /** * Stops a currently active recording session with the specified ID. * * @param id of a currently active recording * @return recorded heap SQL logs for previous recording of the specified ID, empty if no such recording exists */ public Collection stopRecording(String id) { Collection messages = setRecording(null); log.info("Stopped recording of SQL for ID {}. Found {} message(s) on heap.", id, messages.size()); return messages; } /** * Returns the recorded heap SQL logs of the specified recording ID. */ public Collection getLogsById(String id) { return Optional.ofNullable(sqlExecutionListener.getLogsById().get(id)).map(SqlExecutions::getAll).orElse(emptyList()); } /** * Returns all recorded heap SQL logs that match the specified regular expression, regardless of recording ID. */ public Collection getLogsContainingRegex(String regex) { Pattern pattern = Pattern.compile(regex); return getLogs(v -> v.getAll().stream().anyMatch(s -> pattern.matcher(s).find())); } /** * Returns all recorded heap SQL logs that contain an exact case-sensitive match of the specified string, regardless of recording ID. */ public Collection getLogsContaining(String expectedString) { return getLogs(v -> v.getAll().stream().anyMatch(s -> s.contains(expectedString))); } private Collection getLogs(Predicate predicate) { return sqlExecutionListener.getLogsById().values().stream() .filter(predicate) .flatMap(l -> l.getAll().stream()).collect(toList()); } /** * Returns all heap SQL logs, across all recording IDs. */ public Collection getLogs() { return sqlExecutionListener.getLogsById().values().stream().flatMap(l -> l.getAll().stream()).collect(toList()); } /** * Clears all heap SQL logs across all recording sessions. */ public void clearAll() { sqlExecutionListener.getLogsById().clear(); } /** * Clears the heap SQL logs for the specified recording session. */ public void clearLogsForThreadId(String id) { sqlExecutionListener.getLogsById().remove(id); } @Override public Object postProcessBeforeInitialization(final Object bean, final String beanName) throws BeansException { return bean; } @Override public Object postProcessAfterInitialization(final Object bean, final String beanName) throws BeansException { if (bean instanceof DataSource) { ProxyDataSourceBuilder builder = ProxyDataSourceBuilder.create((DataSource) bean) .connectionIdManager(new DefaultConnectionIdManager()); if (this.traceMethods) builder.traceMethods(); if (this.logQueries) builder.logQueryBySlf4j(SLF4JLogLevel.DEBUG); return builder.listener(sqlExecutionListener).build(); } return bean; } SqlRecording getRecording() { return recording.get(); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy