Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement LogCollector #88

Merged
merged 7 commits into from
May 31, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 95 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,11 @@

<fabric8.version>6.13.0</fabric8.version>
<log4j.version>2.17.2</log4j.version>
<slf4j.version>1.7.36</slf4j.version>

<!-- TEST dependencies -->
<mockito.version>5.11.0</mockito.version>
<apache.commons.version>2.16.1</apache.commons.version>

<!-- Build tools' properties -->
<spotbugs.version>4.7.3</spotbugs.version>
Expand All @@ -93,6 +98,10 @@
<maven.surefire.version>3.2.2</maven.surefire.version>
<jackson-dataformat-yaml.version>2.17.1</jackson-dataformat-yaml.version>

<it.skip>true</it.skip>
<!--suppress UnresolvedMavenProperty -->
<ut.skip>${skipTests}</ut.skip>

<checkstyle.config.location>checkstyle.xml</checkstyle.config.location>
</properties>

Expand All @@ -108,6 +117,11 @@
<artifactId>test-frame-kubernetes</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.skodjob</groupId>
<artifactId>test-frame-log-collector</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.fabric8</groupId>
<artifactId>kubernetes-client-bom-with-deps</artifactId>
Expand Down Expand Up @@ -171,6 +185,29 @@
<artifactId>log4j-slf4j-impl</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>${mockito.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
<version>${mockito.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>${apache.commons.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
</dependencyManagement>

Expand Down Expand Up @@ -258,10 +295,65 @@
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>${maven.surefire.version}</version>
<executions>
<execution>
<goals>
<goal>verify</goal>
<goal>integration-test</goal>
</goals>
</execution>
</executions>
<configuration>
<skipITs>${it.skip}</skipITs>
<forkCount>1</forkCount>
<includes>
<include>**/IT*.java</include>
<include>**/*IT.java</include>
</includes>
<properties>
<configurationParameters>
junit.jupiter.extensions.autodetection.enabled = true
</configurationParameters>
</properties>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>${maven.surefire.version}</version>
<inherited>true</inherited>
<configuration>
<properties>
<configurationParameters>
junit.jupiter.extensions.autodetection.enabled = true
</configurationParameters>
</properties>
<skipTests>${ut.skip}</skipTests>
</configuration>
</plugin>
</plugins>
</build>

<profiles>
<profile>
<id>integration</id>
<properties>
<it.skip>false</it.skip>
<ut.skip>true</ut.skip>
</properties>
<modules>
<module>test-frame-common</module>
<module>test-frame-kubernetes</module>
<module>test-frame-openshift</module>
<module>test-frame-test-examples</module>
<module>test-frame-metrics-collector</module>
<module>test-frame-log-collector</module>
</modules>
</profile>
<profile>
<id>default</id>
<activation>
Expand All @@ -273,6 +365,7 @@
<module>test-frame-openshift</module>
<module>test-frame-test-examples</module>
<module>test-frame-metrics-collector</module>
<module>test-frame-log-collector</module>
</modules>
</profile>
<profile>
Expand All @@ -285,6 +378,7 @@
<module>test-frame-kubernetes</module>
<module>test-frame-openshift</module>
<module>test-frame-metrics-collector</module>
<module>test-frame-log-collector</module>
</modules>
<properties>
<!--suppress UnresolvedMavenProperty -->
Expand Down Expand Up @@ -347,6 +441,7 @@
<descriptor>test-frame-kubernetes/src/main/assembly/dist.xml</descriptor>
<descriptor>test-frame-openshift/src/main/assembly/dist.xml</descriptor>
<descriptor>test-frame-metrics-collector/src/main/assembly/dist.xml</descriptor>
<descriptor>test-frame-log-collector/src/main/assembly/dist.xml</descriptor>
</descriptors>
</configuration>
</execution>
Expand Down
21 changes: 0 additions & 21 deletions test-frame-common/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -108,25 +108,4 @@
<artifactId>log4j-slf4j-impl</artifactId>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>${maven.surefire.version}</version>
<configuration>
<test>io.skodjob.testframe.**</test>
<properties>
<configurationParameters>
junit.jupiter.extensions.autodetection.enabled = true
</configurationParameters>
</properties>
<environmentVariables>
<TEST_LOG_LEVEL>DEBUG</TEST_LOG_LEVEL>
</environmentVariables>
</configuration>
</plugin>
</plugins>
</build>
</project>
161 changes: 161 additions & 0 deletions test-frame-log-collector/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
# LogCollector

Utility for collecting logs from Pods and their containers, description of Pods, and YAML descriptions for specified
list of resources in desired Namespaces.
The logs are stored in root folder (which user specifies) within the corresponding folder named after the Namespace
it collects from.

## Prerequisites

- Java 17 and higher
- Access to a Kubernetes cluster
- Kubernetes Client and Command Line Tools (kubectl) setup in your Java environment.

## Installation

In case you are using Maven, you can install the LogCollector dependencies using this code snippet added into `pom.xml`:

```xml
<dependencies>
<dependency>
<groupId>io.skodjob.testframe</groupId>
<artifactId>test-frame-log-collector</artifactId>
<version>{version}</version>
</dependency>
</dependencies>
```

## Usage

### Configuration and initialization

For building the `LogCollector` instance, you can use the `LogCollectorBuilder`.
In the builder, you can specify the list of resources that should be checked during the log collection, or a path to
folder, where all the logs/descriptions should be stored.

The initialization of `LogCollector` object can look like follows:

```java
import io.skodjob.testframe.LogCollector;
import io.skodjob.testframe.LogCollectorBuilder;

LogCollector logCollector = new LogCollectorBuilder()
.withResources("secret", "deployment", "my-custom-resource")
.withRootFolderPath("/path/to/logs/folder")
.build();
```

### Collecting logs and descriptions

Each Namespace has its own directory in the root folder, where everything collected is stored to.
For each resource specified in the list, the folder is created and all the YAMLs are stored there - only in case that
there are resources with the specified resource kind.
Otherwise, the folder is not created.
This is the list of things that are collected by default (without specifying them in the resource list):

- Events of the Namespace - `kubectl get events -n NAMESPACE`
- Pod description - `kubectl describe pod POD_NAME -n NAMESPACE`
- Logs from each Pod and its container(s) - `kubectl logs POD_NAME -c CONTAINER_NAME -n NAMESPACE`

In LogCollector, you can collect the logs and resource descriptions using multiple methods, based on your needs:

#### 1. Collect from single Namespace with specified name

```java
import io.skodjob.testframe.LogCollector;
import io.skodjob.testframe.LogCollectorBuilder;

LogCollector logCollector = new LogCollectorBuilder()
.withResources("secret", "deployment", "my-custom-resource")
.withRootFolderPath("/path/to/logs/folder")
.build();

public static void collectFromNamespace() {
logCollector.collectFromNamespace("my-namespace");
}
```
the logs path will then look like this:
```bash
/path/to/logs/folder
└── my-namespace
├── deployment
├── events.log
├── my-custom-resource
├── pods
└── secret
```

#### 2. Collect from multiple Namespaces with specified names:

```java
import io.skodjob.testframe.LogCollector;
import io.skodjob.testframe.LogCollectorBuilder;

LogCollector logCollector = new LogCollectorBuilder()
.withResources("secret", "deployment", "my-custom-resource")
.withRootFolderPath("/path/to/logs/folder")
.build();

public static void collectFromNamespaces() {
logCollector.collectFromNamespaces("my-namespace", "my-namespace2");
}
```
the logs path will then look like this:
```bash
/path/to/logs/folder
├── my-namespace
│ ├── deployment
│ ├── events.log
│ ├── pods
│ └── secret
└── my-namespace2
├── deployment
├── events.log
├── pods
└── secret

```
#### 3. Collect from Namespaces matching labels

Let's assume that `my-namespace` in this example is the one containing our specified labels and we have other Namespaces
that don't have this label.
Then to collect logs and YAMLs from those Namespaces, that are matching the labels, you can do:

```java
import io.fabric8.kubernetes.api.model.LabelSelectorBuilder;
import io.skodjob.testframe.LogCollector;
import io.skodjob.testframe.LogCollectorBuilder;

LogCollector logCollector = new LogCollectorBuilder()
.withResources("secret", "deployment", "my-custom-resource")
.withRootFolderPath("/path/to/logs/folder")
.build();

public static void collectFromNamespaces() {
logCollector.collectFromNamespaceWithLabels(new LabelSelectorBuilder()
.withMatchLabels(Map.of("my-label", "my-value"))
);
}
```

The tree path will look similarly to above examples, there will be folders for Namespaces matching the specified labels.

### Changing the root folder path

In case that you would like to change the root path, there is a method for that in the `LogCollector` object itself:

```java
import io.skodjob.testframe.LogCollector;
import io.skodjob.testframe.LogCollectorBuilder;
import org.junit.jupiter.api.AfterEach;

LogCollector logCollector = new LogCollectorBuilder()
.withResources("secret", "deployment", "my-custom-resource")
.withRootFolderPath("/path/to/logs/folder")
.build();

@AfterEach
void changeRootPath() {
logCollector.changeRootFolderPath("/path/to/another/folder");
}
```
Loading
Loading