diff --git a/.gitpod.yml b/.gitpod.yml index 9f6da64..6e0cc81 100644 --- a/.gitpod.yml +++ b/.gitpod.yml @@ -1,6 +1,6 @@ # Image of workspace. Learn more: https://www.gitpod.io/docs/configure/workspaces/workspace-image image: maeddes/gitpod:full -workspaceLocation: '/workspace/otel-getting-started/labs' +workspaceLocation: '/workspace/otel-getting-started' tasks: - name: Add Python Otel libs @@ -9,4 +9,4 @@ tasks: init: echo 127.0.0.1 httpbin | sudo tee -a /etc/hosts command: docker run -p 80:80 kennethreitz/httpbin - name: Start tutorial - command: docker compose up tutorial \ No newline at end of file + command: docker compose up tutorial diff --git a/labs/automatic-instrumentation/solution/todobackend-springboot/Dockerfile b/labs/automatic-instrumentation/solution/todobackend-springboot/Dockerfile new file mode 100644 index 0000000..b7beec4 --- /dev/null +++ b/labs/automatic-instrumentation/solution/todobackend-springboot/Dockerfile @@ -0,0 +1,23 @@ +FROM docker.io/maven:3-eclipse-temurin-21 as build +WORKDIR /workspace/app + +COPY pom.xml . +COPY src src + +RUN --mount=type=cache,target=/root/.m2 mvn install -DskipTests +RUN mkdir -p target/dependency && (cd target/dependency; jar -xf ../*.jar) + +FROM docker.io/eclipse-temurin:21-jdk-alpine +RUN mkdir -p /opt/todobackend +WORKDIR /opt/todobackend +#RUN addgroup -S demo && adduser -S demo -G demo +#USER demo +VOLUME /tmp +ARG DEPENDENCY=/workspace/app/target/dependency +COPY --from=build ${DEPENDENCY}/BOOT-INF/lib /opt/todobackend/app/lib +COPY --from=build ${DEPENDENCY}/META-INF /opt/todobackend/app/META-INF +COPY --from=build ${DEPENDENCY}/BOOT-INF/classes /opt/todobackend/app + +ADD https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/latest/download/opentelemetry-javaagent.jar /opt/todobackend + +ENTRYPOINT ["java", "-cp", "/opt/todobackend/app:/opt/todobackend/app/lib/*", "-javaagent:/opt/todobackend/opentelemetry-javaagent.jar","io.novatec.todobackend.TodobackendApplication"] \ No newline at end of file diff --git a/labs/automatic-instrumentation/solution/todobackend-springboot/pom.xml b/labs/automatic-instrumentation/solution/todobackend-springboot/pom.xml new file mode 100644 index 0000000..79c0651 --- /dev/null +++ b/labs/automatic-instrumentation/solution/todobackend-springboot/pom.xml @@ -0,0 +1,74 @@ + + + 4.0.0 + + + org.springframework.boot + spring-boot-starter-parent + 3.2.2 + + + + io.novatec + todobackend + 0.0.1-SNAPSHOT + todobackend + Novatec Demo Application + + + 21 + + + + + org.springframework.boot + spring-boot-starter-actuator + + + org.springframework.boot + spring-boot-starter-data-jpa + + + org.springframework.boot + spring-boot-starter-web + + + com.h2database + h2 + runtime + + + org.postgresql + postgresql + runtime + + + org.springdoc + springdoc-openapi-starter-webmvc-ui + 2.2.0 + + + org.springframework.boot + spring-boot-starter-test + test + + + io.opentelemetry.instrumentation + opentelemetry-instrumentation-annotations + 1.29.0 + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + \ No newline at end of file diff --git a/labs/automatic-instrumentation/solution/todobackend-springboot/src/main/java/io/novatec/todobackend/TodobackendApplication.java b/labs/automatic-instrumentation/solution/todobackend-springboot/src/main/java/io/novatec/todobackend/TodobackendApplication.java new file mode 100644 index 0000000..b058c45 --- /dev/null +++ b/labs/automatic-instrumentation/solution/todobackend-springboot/src/main/java/io/novatec/todobackend/TodobackendApplication.java @@ -0,0 +1,144 @@ +package io.novatec.todobackend; + +import java.util.ArrayList; +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.data.repository.CrudRepository; +import org.springframework.web.bind.annotation.*; + +import io.opentelemetry.instrumentation.annotations.SpanAttribute; +import io.opentelemetry.instrumentation.annotations.WithSpan; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; + +@SpringBootApplication +@RestController +@CrossOrigin(origins = "*") + +public class TodobackendApplication { + + private Logger logger = LoggerFactory.getLogger(TodobackendApplication.class); + + @Value("${HOSTNAME:not_set}") + String hostname; + + @Value("${spring.profiles.active: none}") + String profile; + + @Autowired + TodoRepository todoRepository; + + private String getInstanceId() { + + if (!hostname.equals("not_set")) + return hostname; + return "probably localhost"; + + } + + @GetMapping("/hello") + String hello() { + + return getInstanceId() + " Hallo, Welt ! "; + + } + + @GetMapping("/fail") + String fail() { + + System.exit(1); + return "fixed!"; + } + + @GetMapping("/todos/") + List getTodos(){ + + logger.info(cfInstance); + + List todos = new ArrayList(); + + todoRepository.findAll().forEach(todo -> todos.add(todo.getTodo())); + logger.info("GET /todos/ "+todos.toString()); + + + return todos; + } + + @PostMapping("/todos/{todo}") + String addTodo(@PathVariable String todo){ + + this.someInternalMethod(todo); + //todoRepository.save(new Todo(todo)); + logger.info("POST /todos/ "+todo.toString()); + + return todo; + + } + + @WithSpan + String someInternalMethod(@SpanAttribute String todo){ + + todoRepository.save(new Todo(todo)); + if(todo.equals("slow")){ + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + if(todo.equals("fail")){ + + System.out.println("Failing ..."); + throw new RuntimeException(); + + } + return todo; + + } + + @DeleteMapping("/todos/{todo}") + String removeTodo(@PathVariable String todo) { + + todoRepository.deleteById(todo); + logger.info("DELETE /todos/ "+todo.toString()); + return "removed "+todo; + + } + + public static void main(String[] args) { + SpringApplication.run(TodobackendApplication.class, args); + } +} + +@Entity +class Todo{ + + @Id + String todo; + + public Todo(){} + + public Todo(String todo){ + this.todo = todo; + } + + public String getTodo(){ + return todo; + } + + public void setTodo(String todo) { + this.todo = todo; + } + +} + +interface TodoRepository extends CrudRepository { + +} \ No newline at end of file diff --git a/labs/automatic-instrumentation/solution/todobackend-springboot/src/main/resources/application-dev.properties b/labs/automatic-instrumentation/solution/todobackend-springboot/src/main/resources/application-dev.properties new file mode 100644 index 0000000..25d7606 --- /dev/null +++ b/labs/automatic-instrumentation/solution/todobackend-springboot/src/main/resources/application-dev.properties @@ -0,0 +1,5 @@ +spring.h2.console.enabled=true +spring.h2.console.path=/h2 +spring.datasource.url=jdbc:h2:mem:testdb +spring.datasource.username=sa +spring.datasource.password= \ No newline at end of file diff --git a/labs/automatic-instrumentation/solution/todobackend-springboot/src/main/resources/application-prod.properties b/labs/automatic-instrumentation/solution/todobackend-springboot/src/main/resources/application-prod.properties new file mode 100644 index 0000000..6806431 --- /dev/null +++ b/labs/automatic-instrumentation/solution/todobackend-springboot/src/main/resources/application-prod.properties @@ -0,0 +1,3 @@ +spring.datasource.url= jdbc:postgresql://${POSTGRES_HOST:postgresdb}:5432/mydb +spring.datasource.username=matthias +spring.datasource.password=password \ No newline at end of file diff --git a/labs/automatic-instrumentation/solution/todobackend-springboot/src/main/resources/application.properties b/labs/automatic-instrumentation/solution/todobackend-springboot/src/main/resources/application.properties new file mode 100644 index 0000000..eaa2173 --- /dev/null +++ b/labs/automatic-instrumentation/solution/todobackend-springboot/src/main/resources/application.properties @@ -0,0 +1,13 @@ +server.port=8080 + +server.forward-headers-strategy=native +management.endpoints.web.exposure.include=* + +spring.profiles.active=dev + +spring.jpa.hibernate.ddl-auto=update +spring.jpa.show-sql=true +#spring.jpa.properties.hibernate.format_sql=true + +spring.application.name=springboot-backend +otel.exporter.otlp.endpoint=http://${COLLECTOR_HOST:localhost}:4317 diff --git a/labs/automatic-instrumentation/solution/todobackend-springboot/src/test/java/io/novatec/todobackend/TodobackendApplicationIntegrationTests.java b/labs/automatic-instrumentation/solution/todobackend-springboot/src/test/java/io/novatec/todobackend/TodobackendApplicationIntegrationTests.java new file mode 100755 index 0000000..b18589d --- /dev/null +++ b/labs/automatic-instrumentation/solution/todobackend-springboot/src/test/java/io/novatec/todobackend/TodobackendApplicationIntegrationTests.java @@ -0,0 +1,12 @@ +package io.novatec.todobackend; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +public class TodobackendApplicationIntegrationTests { + + @Test + void contextLoads() { + } +} \ No newline at end of file