java - 从 jenkins 中的 docker 容器获取日志

标签 java docker jenkins jenkins-pipeline jenkins-docker

我正在尝试让 docker 设置一个完整的测试环境,我可以在其中运行集成测试,但到目前为止它并没有真正起作用,我什至在从中获取日志时遇到问题。

所以我想将它作为管道运行并且我想使用 jenkinsfile。这是我到目前为止得到的:

pipeline {
    agent any
    stages {
        stage('build war') {
            agent {
                docker { 
                    image 'gradle:latest'
                    reuseNode true 
                }
            }
            steps {
                sh 'gradle war -b oven/build.gradle'
            }
        }
        stage('test') {
            steps {
                script {
                    docker.image('mysql:latest').withRun('-e "MYSQL_ROOT_PASSWORD=password" -e "MYSQL_USER=root" -e "MYSQL_DATABASE=highlygroceries"') { c -> 
                        docker.image('munhunger/highly-oven').withRun('-e "test=test"') { h -> 
                            docker.image('mysql:latest').inside("--link ${c.id}:db") {
                                sh 'while ! mysqladmin ping -hdb --silent; do sleep 1; done'
                            }
                            docker.image('munhunger/highly-oven').inside("--link ${c.id}:db -e 'DB_URL=db:3306' -e 'DB_PASS=password' -e 'DB_USER=root'") {
                                sh 'sleep 5'
                            }
                            docker.image('gradle:latest').inside("--link ${h.id}:backend -e 'OVEN_URL=http://backend:8080'") {
                                sh 'gradle test -b oven/build.gradle'
                            }
                            sh "docker logs ${h.id}"
                        }
                    }
                }
            }
        }
        stage('build dockerimage') {
            steps {
                script {
                    dir('oven') {
                        def image = docker.build("munhunger/highly-oven")

                        docker.withRegistry('https://registry.hub.docker.com', 'docker-hub-credentials') {
                            image.push("${env.BUILD_NUMBER}")
                            image.push("latest")
                        }
                    }
                }
            }
        }
    }
}

但是我的后端和数据库的连接好像有问题……

我从构建日志中得到的只是:

se.munhunger.oven.rest.UserTest > System is up and running, Creating a user, it returns 204 upon creation FAILED
    java.lang.AssertionError at UserTest.java:38

指向:

                Assert.assertEquals("non 204 from backend", 204,
                                    client.target(baseURL + "/api/user")
                                        .request()
                                        .header("email", "mail@mail.mail")
                                        .post(Entity.json(null))
                                        .getStatus());

我相信测试器和后端之间的连接是正常的,因为下面的测试成功了

            Assert.assertEquals(200,
                                client.target(baseURL + "/swagger")
                                    .request()
                                    .get()
                                    .getStatus());

这让我想到了如何从后端 docker 镜像中获取日志的主要问题? 我觉得没有它,几乎不可能调试出了什么问题

编辑 我得到了一些日志,但在错误的时间。 如果我更改为以下内容:

                docker.image('mysql:latest').withRun('-e "MYSQL_ROOT_PASSWORD=password" -e "MYSQL_USER=root" -e "MYSQL_DATABASE=highlygroceries"') { c -> 
                    docker.image('munhunger/highly-oven').withRun('-e "test=test"') { h -> 
                        docker.image('mysql:latest').inside("--link ${c.id}:db") {
                            sh 'while ! mysqladmin ping -hdb --silent; do sleep 1; done'
                        }
                        docker.image('munhunger/highly-oven').inside("--link ${c.id}:db -e 'DB_URL=db:3306' -e 'DB_PASS=password' -e 'DB_USER=root'") {
                            sh 'sleep 5'
                        }
                        sh "docker logs ${h.id}"
                        docker.image('gradle:latest').inside("--link ${h.id}:backend -e 'OVEN_URL=http://backend:8080'") {
                            sh 'gradle test -b oven/build.gradle'
                        }
                        sh "docker logs ${h.id}"
                    }
                }

我从启动中获取所有日志。但它没有在测试失败后打印出日志

最佳答案

当您能够在不使用 Jenkins 文件的情况下运行集成测试时,它会有所帮助,因此您应该使用 docker-compose,而不是使用这些嵌套的 docker.image 语句。

我要像这样进行集成测试:

stage('Run integration tests') {
  steps {
    script {
      try {
        timeout(30) {
          // Tear up integration test environment
          sh "docker-compose up -d"
          // Wait until it is ready
          waitUntil {
            "healthy" == sh(returnStdout: true,
              script: "docker inspect CONTAINER_NAME --format=\"{{ .State.Health.Status }}\"").trim()
          }

          docker.image('IMAGENAME').inside('--network projectname_default') {
            sh "gradle integrationTest"
          }
        }
      } finally {
        try {
          step([$class: 'JUnitResultArchiver', testResults: '**/build/integrationTest-results/TEST-*.xml'])
        } catch (Exception e) {
          // Ignore exception when there are no test results
        }
        sh "docker-compose logs >integration-test.log"
        sh "docker-compose down --rmi local --volumes --remove-orphans"
        archive 'integration-test.log'
      }
    }
  }
}

如您所见,我将 Gradle 测试容器附加到由 docker-compose 设置的网络。这使您不仅可以重新使用您的撰写进行测试。

现在您必须确保您使用的所有容器都记录到标准输出。最后,您会在归档 integration-test.log 中获得所有日志。当然,你也可以扩展它来为每个容器获取一个单独的日志文件。

关于java - 从 jenkins 中的 docker 容器获取日志,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48754493/

相关文章:

java - 如何在java中准确指定依赖的jar版本?

java - .exceptionally()是否会捕获嵌套的Future中抛出的异常?或者在哪里放置.exceptionally()是正确的

docker - 重定向docker中nohup的输出不起作用

jenkins - 如何使用 File 参数作为参数触发下游 jenkins 作业?

php - 从Docker容器访问Nginx时出现502错误的网关

使用 Dockerfile 的 Java Spring Boot 随机端口

docker - 从 Docker buildkit 获取容器 ID 以进行交互式调试

docker - 更改 Docker 容器中的 memlock 限制;是否可以?

git - 与 Angular CLI 和 Jenkins 进行持续集成的好方法

java - 添加数据库关系信息映射到Java数据库?