testcontainers / testcontainers-java

Testcontainers is a Java library that supports JUnit tests, providing lightweight, throwaway instances of common databases, Selenium web browsers, or anything else that can run in a Docker container.
https://testcontainers.org
MIT License
7.97k stars 1.64k forks source link

Allow logging level to be specified during container creation. #4717

Open stsmitz opened 2 years ago

stsmitz commented 2 years ago

I'm currently trying to debug an issue where I can run a postgresql container via the command line and I see that the database starts just fine. But testcontainers throws an IllegalArgumentException -> ContainerLaunchException (apparently it thinksthat the PostgreSQLContainer doesn't start properly). I see in the source code that logging is hard-coded to be turned off during the startup process. It would be nice to have a method of changing this value since the information provided is not very useful for debugging.

kiview commented 2 years ago

Hi @stsmitz, can you please share the code you use for creating and starting the PostgreSQLContainer, since it is not clear from your description what your actual issue is. ContainerLaunchException indicates wait strategy failing, which in case of PostgreSQLContainer is LogMessageWaitStrategy.

stsmitz commented 2 years ago
public abstract class AbstractRdbmsTest {
    @Container
    public static final PostgreSQLContainer CONTAINER;

    static {
        DockerImageName imgName = DockerImageName.parse("centos/postgresql-96-centos7");

        CONTAINER = (PostgreSQLContainer)  new PostgreSQLContainer(imgName)
                .withDatabaseName(POSTGRESQL_DATABASE)
                .withUsername(POSTGRESQL_USER)
                .withPassword(POSTGRESQL_PASSWORD)
                .withEnv("POSTGRESQL_DATABASE", POSTGRESQL_DATABASE)
                .withEnv("POSTGRESQL_USER", POSTGRESQL_USER)
                .withEnv("POSTGRESQL_PASSWORD", POSTGRESQL_PASSWORD)
                .withExposedPorts(PostgreSQLContainer.POSTGRESQL_PORT);

        CONTAINER.setWaitStrategy(new LogMessageWaitStrategy()
                .withRegEx("\\s*/var/run/postgresql:\\d+ - accepting connections\\s*")
                .withStartupTimeout(Duration.of(60, SECONDS)));

        POSTGRESQL_CONTAINER.start();
    }
}

Apparently, the container I'm using is expecting different environment variable prefix (POSTGRESQL vs POSTGRES). Also, I changed the wait strategy because I was getting timeout errors and based it on what I was seeing echoed to stdout when I started the container via the cmd line. I do see in the container /var/lib/pgsql/data/userdata/pg_log/postgresql-[day of week].log file the lines that the original wait strategy is looking to be echoed. So stepping through the code in the debugger I'm only seeing a couple messages being echoed to stderr and the wait strategy is still failing. But I built my own container from the above container just to run yum update to bring the software inline with what we had deployed on our actual servers.

stsmitz commented 2 years ago

The specific code I'm referring to though is in PostgreSQLContainer, in the configure() method, where it explicitly sets the "loggerLevel" URL parameter to "OFF". It would be nice to have the ability to change this to assist in debugging container issues when writing unit tests.

rnorth commented 2 years ago

@stsmitz this isn't exactly what you asked for, but you might get more useful insights by streaming the container logs to SLF4J or another logger: https://www.testcontainers.org/features/container_logs/#streaming-logs

stsmitz commented 2 years ago

I will definitely turn that on. That is a lot easier than stepping through in the debugger and doing it via a watch expression.

kiview commented 2 years ago

You can also set a breakpoint and check out the logs using Docker CLI's docker log command. If you using an unsupported image, you have to indeed configure the wait strategy accordingly.