BAEL-6444 | Added P6Spy logging in spring boot observation module. (#13965)
* BAEL-6444 | Added P6Spy logging in spring boot observation module. * BAEL-6444 | Added Find with name query and custom log format now working * BAEL-6444 | Formatting * BAEL-6444 | Renaming junit files * BAEL-6444 | Added start class * BAEL-6444 | Actualized code with Article * BAEL-6444 | Actualized code with Article * BAEL-6444 | redded commit() * BAEL-6444 | BDD naming strategy
This commit is contained in:
parent
e16bd13cc8
commit
579ba7726f
|
@ -54,6 +54,25 @@
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-aop</artifactId>
|
<artifactId>spring-boot-starter-aop</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-jdbc</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<!-- get latest version from https://github.com/gavlyukovskiy/spring-boot-data-source-decorator/releases-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.github.gavlyukovskiy</groupId>
|
||||||
|
<artifactId>p6spy-spring-boot-starter</artifactId>
|
||||||
|
<version>1.9.0</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.h2database</groupId>
|
||||||
|
<artifactId>h2</artifactId>
|
||||||
|
<scope>runtime</scope>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-devtools</artifactId>
|
<artifactId>spring-boot-devtools</artifactId>
|
||||||
|
@ -63,4 +82,8 @@
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<start-class>com.baeldung.samples.SimpleObservationApplication</start-class>
|
||||||
|
</properties>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2017 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.baeldung.p6spy;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
|
||||||
|
@SpringBootApplication
|
||||||
|
public class SampleP6SpyApplication {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(SampleP6SpyApplication.class, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,54 @@
|
||||||
|
package com.baeldung.p6spy.controllers;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import javax.sql.DataSource;
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.Statement;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("jdbc")
|
||||||
|
public class JDBCController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private DataSource dataSource;
|
||||||
|
|
||||||
|
@RequestMapping("/commit")
|
||||||
|
public List<Map<String, String>> select() {
|
||||||
|
List<Map<String, String>> results = new ArrayList<>();
|
||||||
|
try {
|
||||||
|
Connection connection = dataSource.getConnection();
|
||||||
|
Statement statement = connection.createStatement();
|
||||||
|
statement.executeQuery("SELECT * FROM student");
|
||||||
|
connection.commit();
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new IllegalStateException(e);
|
||||||
|
}
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequestMapping("/rollback")
|
||||||
|
public List<Map<String, String>> rollback() {
|
||||||
|
List<Map<String, String>> results = new ArrayList<>();
|
||||||
|
try (Connection connection = dataSource.getConnection()) {
|
||||||
|
connection.rollback();
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new IllegalStateException(e);
|
||||||
|
}
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequestMapping("/query-error")
|
||||||
|
public void error() {
|
||||||
|
try (Connection connection = dataSource.getConnection();
|
||||||
|
Statement statement = connection.createStatement()) {
|
||||||
|
statement.execute("SELECT UNDEFINED()");
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
package com.baeldung.p6spy.controllers;
|
||||||
|
|
||||||
|
import com.baeldung.p6spy.repository.Student;
|
||||||
|
import com.baeldung.p6spy.repository.StudentRepository;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("student")
|
||||||
|
public class StudentController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private StudentRepository repository;
|
||||||
|
|
||||||
|
@RequestMapping("/save")
|
||||||
|
public Long save() {
|
||||||
|
return repository.save(new Student("Pablo", "Picasso")).getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequestMapping("/find/{name}")
|
||||||
|
public List<Student> getAll(@PathVariable String name) {
|
||||||
|
return repository.findAllByFirstName(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
package com.baeldung.p6spy.repository;
|
||||||
|
|
||||||
|
import jakarta.persistence.Entity;
|
||||||
|
import jakarta.persistence.GeneratedValue;
|
||||||
|
import jakarta.persistence.Id;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
public class Student {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@GeneratedValue
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
private String firstName;
|
||||||
|
private String lastName;
|
||||||
|
|
||||||
|
public Student() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public Student(String firstName, String lastName) {
|
||||||
|
this.firstName = firstName;
|
||||||
|
this.lastName = lastName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFirstName() {
|
||||||
|
return firstName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFirstName(String firstName) {
|
||||||
|
this.firstName = firstName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLastName() {
|
||||||
|
return lastName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLastName(String lastName) {
|
||||||
|
this.lastName = lastName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Student{" + "id=" + id + ", firstName='" + firstName + '\'' + ", lastName='" + lastName + '\'' + '}';
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
package com.baeldung.p6spy.repository;
|
||||||
|
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Repository
|
||||||
|
public interface StudentRepository extends JpaRepository<Student, Long> {
|
||||||
|
List<Student> findAllByFirstName(String firstName);
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
# specifies the appender to use for logging
|
||||||
|
# Please note: reload means forgetting all the previously set
|
||||||
|
# settings (even those set during runtime - via JMX)
|
||||||
|
# and starting with the clean table
|
||||||
|
# (only the properties read from the configuration file)
|
||||||
|
# (default is com.p6spy.engine.spy.appender.FileLogger)
|
||||||
|
#appender=com.p6spy.engine.spy.appender.Slf4JLogger
|
||||||
|
#appender=com.p6spy.engine.spy.appender.StdoutLogger
|
||||||
|
appender=com.p6spy.engine.spy.appender.FileLogger
|
||||||
|
|
||||||
|
# name of logfile to use, note Windows users should make sure to use forward slashes in their pathname (e:/test/spy.log)
|
||||||
|
# (used for com.p6spy.engine.spy.appender.FileLogger only)
|
||||||
|
# (default is spy.log)
|
||||||
|
logfile=database.log
|
||||||
|
|
||||||
|
# append to the p6spy log file. if this is set to false the
|
||||||
|
# log file is truncated every time. (file logger only)
|
||||||
|
# (default is true)
|
||||||
|
append=true
|
||||||
|
|
||||||
|
# class to use for formatting log messages (default is: com.p6spy.engine.spy.appender.SingleLineFormat)
|
||||||
|
logMessageFormat=com.p6spy.engine.spy.appender.CustomLineFormat
|
||||||
|
|
||||||
|
# Custom log message format used ONLY IF logMessageFormat is set to com.p6spy.engine.spy.appender.CustomLineFormat
|
||||||
|
# default is %(currentTime)|%(executionTime)|%(category)|connection%(connectionId)|%(sqlSingleLine)
|
||||||
|
# Available placeholders are:
|
||||||
|
# %(connectionId) the id of the connection
|
||||||
|
# %(currentTime) the current time expressing in milliseconds
|
||||||
|
# %(executionTime) the time in milliseconds that the operation took to complete
|
||||||
|
# %(category) the category of the operation
|
||||||
|
# %(effectiveSql) the SQL statement as submitted to the driver
|
||||||
|
# %(effectiveSqlSingleLine) the SQL statement as submitted to the driver, with all new lines removed
|
||||||
|
# %(sql) the SQL statement with all bind variables replaced with actual values
|
||||||
|
# %(sqlSingleLine) the SQL statement with all bind variables replaced with actual values, with all new lines removed
|
||||||
|
customLogMessageFormat=%(currentTime)|%(executionTime)|%(category)|%(sqlSingleLine)
|
||||||
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2017 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.baeldung.p6spy;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Assertions;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||||
|
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||||
|
import org.springframework.web.client.RestTemplate;
|
||||||
|
|
||||||
|
@ExtendWith(SpringExtension.class)
|
||||||
|
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
|
||||||
|
class JDBCControllerIntegrationTest {
|
||||||
|
|
||||||
|
private final RestTemplate restTemplate = new RestTemplate();
|
||||||
|
@Value("http://localhost:${local.server.port}/jdbc")
|
||||||
|
private String localhost;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testJdbcCommitRESTMethod_isSuccessful() {
|
||||||
|
Assertions.assertTrue(restTemplate.getForEntity(localhost + "/commit", String.class)
|
||||||
|
.getStatusCode().is2xxSuccessful());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void jdbcRollbackRESTMethod_isSuccessful() {
|
||||||
|
Assertions.assertTrue(restTemplate.getForEntity(localhost + "/rollback", String.class)
|
||||||
|
.getStatusCode().is2xxSuccessful());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void jdbcQueryErrorRESTMethod_isSuccessful() {
|
||||||
|
Assertions.assertTrue(restTemplate.getForEntity(localhost + "/query-error", String.class)
|
||||||
|
.getStatusCode().is2xxSuccessful());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,49 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2021 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.baeldung.p6spy;
|
||||||
|
|
||||||
|
import com.github.gavlyukovskiy.boot.jdbc.decorator.DecoratedDataSource;
|
||||||
|
import com.github.gavlyukovskiy.boot.jdbc.decorator.p6spy.P6SpyDataSourceDecorator;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||||
|
|
||||||
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
@ExtendWith(SpringExtension.class)
|
||||||
|
@SpringBootTest
|
||||||
|
class SampleP6SpyApplicationIntegrationTest {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private DataSource dataSource;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void whenP6SpyEnabled_datasourceIsDecorated() {
|
||||||
|
assertThat(dataSource).isInstanceOf(DecoratedDataSource.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void whenP6SpyEnabled_decoratingChainContainsP6Spy() {
|
||||||
|
DecoratedDataSource decoratedDataSource = (DecoratedDataSource) dataSource;
|
||||||
|
assertThat(decoratedDataSource.getDecoratingChain().get(0).getDataSourceDecorator()).isInstanceOf(P6SpyDataSourceDecorator.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
# specifies the appender to use for logging.
|
||||||
|
# used to avoid the creation of logging file with tests.
|
||||||
|
appender=com.p6spy.engine.spy.appender.StdoutLogger
|
Loading…
Reference in New Issue