Skip to content

Commit fb56ca6

Browse files
rgoersppkarwasz
authored andcommitted
Add kubernetes-log4j module
This module adds the ability to Log4j Core to use Kubernetes attributes in a configuration file. It is a cleaned-up version of the `org.apache.logging.log4j:log4j-kubernetes`. As explained in #5682, it does make more sense to host is here since: * it only depends on a very stable `StrLookup` dependency from `log4j-core`, * the number and kind of properties available through `kubernetes-client` depend on its version.
1 parent e7f734b commit fb56ca6

File tree

11 files changed

+1249
-0
lines changed

11 files changed

+1249
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#### Dependency Upgrade
1212

1313
#### New Features
14+
* Add a `kubernetes-log4j` module to lookup Kubernetes attributes in a Log4j Core configuration.
1415

1516
#### _**Note**_: Breaking changes
1617

log4j/pom.xml

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
4+
Copyright (C) 2015 Red Hat, Inc.
5+
6+
Licensed under the Apache License, Version 2.0 (the "License");
7+
you may not use this file except in compliance with the License.
8+
You may obtain a copy of the License at
9+
10+
http://www.apache.org/licenses/LICENSE-2.0
11+
12+
Unless required by applicable law or agreed to in writing, software
13+
distributed under the License is distributed on an "AS IS" BASIS,
14+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
See the License for the specific language governing permissions and
16+
limitations under the License.
17+
18+
-->
19+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
20+
<modelVersion>4.0.0</modelVersion>
21+
<parent>
22+
<groupId>io.fabric8</groupId>
23+
<artifactId>kubernetes-client-project</artifactId>
24+
<version>6.11-SNAPSHOT</version>
25+
</parent>
26+
27+
<artifactId>kubernetes-log4j</artifactId>
28+
<packaging>jar</packaging>
29+
<name>Fabric8 :: Kubernetes :: Log4j Core components</name>
30+
<description>Provides a lookup to use Kubernetes attributes in a Log4j Core configuration.</description>
31+
32+
<properties>
33+
<osgi.export>io.fabric8.kubernetes.log4j.*</osgi.export>
34+
<osgi.import>*</osgi.import>
35+
</properties>
36+
37+
<dependencies>
38+
<dependency>
39+
<groupId>io.fabric8</groupId>
40+
<artifactId>kubernetes-client</artifactId>
41+
</dependency>
42+
<dependency>
43+
<groupId>io.fabric8</groupId>
44+
<artifactId>kubernetes-model-core</artifactId>
45+
</dependency>
46+
<dependency>
47+
<groupId>org.apache.logging.log4j</groupId>
48+
<artifactId>log4j-core</artifactId>
49+
</dependency>
50+
<dependency>
51+
<groupId>org.junit.jupiter</groupId>
52+
<artifactId>junit-jupiter-api</artifactId>
53+
<scope>test</scope>
54+
</dependency>
55+
<dependency>
56+
<groupId>org.junit.jupiter</groupId>
57+
<artifactId>junit-jupiter-params</artifactId>
58+
<scope>test</scope>
59+
</dependency>
60+
</dependencies>
61+
62+
<build>
63+
<plugins>
64+
<!-- Replace `jar:jar` execution with `bundle:bundle` -->
65+
<plugin>
66+
<groupId>org.apache.maven.plugins</groupId>
67+
<artifactId>maven-jar-plugin</artifactId>
68+
<executions>
69+
<execution>
70+
<id>default-jar</id>
71+
<phase>none</phase>
72+
</execution>
73+
</executions>
74+
</plugin>
75+
<plugin>
76+
<groupId>org.apache.felix</groupId>
77+
<artifactId>maven-bundle-plugin</artifactId>
78+
<executions>
79+
<execution>
80+
<id>generate-osgi-bundle</id>
81+
<goals>
82+
<goal>bundle</goal>
83+
</goals>
84+
</execution>
85+
</executions>
86+
</plugin>
87+
</plugins>
88+
</build>
89+
</project>
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/**
2+
* Copyright (C) 2015 Red Hat, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package io.fabric8.kubernetes.log4j.lookup;
17+
18+
import io.fabric8.kubernetes.client.Config;
19+
import io.fabric8.kubernetes.client.ConfigBuilder;
20+
import io.fabric8.kubernetes.client.KubernetesClient;
21+
import io.fabric8.kubernetes.client.KubernetesClientBuilder;
22+
23+
/**
24+
* Builds a Kubernetes Client.
25+
*/
26+
class ClientBuilder {
27+
28+
public KubernetesClient createClient() {
29+
final Config config = kubernetesClientConfig();
30+
return config != null ? new KubernetesClientBuilder()
31+
.withConfig(config).build() : null;
32+
}
33+
34+
private Config kubernetesClientConfig() {
35+
Config base = null;
36+
try {
37+
base = Config.autoConfigure(null);
38+
} catch (Exception ex) {
39+
if (ex instanceof NullPointerException) {
40+
return null;
41+
}
42+
}
43+
final ClientProperties props = new ClientProperties(base);
44+
final Config properties = new ConfigBuilder(base)
45+
.withApiVersion(props.getApiVersion())
46+
.withCaCertData(props.getCaCertData())
47+
.withCaCertFile(props.getCaCertFile())
48+
.withClientCertData(props.getClientCertData())
49+
.withClientCertFile(props.getClientCertFile())
50+
.withClientKeyAlgo(props.getClientKeyAlgo())
51+
.withClientKeyData(props.getClientKeyData())
52+
.withClientKeyFile(props.getClientKeyFile())
53+
.withClientKeyPassphrase(props.getClientKeyPassphrase())
54+
.withConnectionTimeout(props.getConnectionTimeout())
55+
.withHttpProxy(props.getHttpProxy())
56+
.withHttpsProxy(props.getHttpsProxy())
57+
.withMasterUrl(props.getMasterUrl())
58+
.withNamespace(props.getNamespace())
59+
.withNoProxy(props.getNoProxy())
60+
.withPassword(props.getPassword())
61+
.withProxyPassword(props.getProxyPassword())
62+
.withProxyUsername(props.getProxyUsername())
63+
.withRequestTimeout(props.getRequestTimeout())
64+
.withTrustCerts(props.isTrustCerts())
65+
.withUsername(props.getUsername())
66+
.build();
67+
return properties;
68+
}
69+
}
Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
/**
2+
* Copyright (C) 2015 Red Hat, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package io.fabric8.kubernetes.log4j.lookup;
17+
18+
import io.fabric8.kubernetes.client.Config;
19+
import org.apache.logging.log4j.util.PropertiesUtil;
20+
21+
import java.time.Duration;
22+
23+
/**
24+
* Obtains properties used to configure the Kubernetes client.
25+
*/
26+
class ClientProperties {
27+
28+
private static final String[] PREFIXES = { "log4j2.kubernetes.client.", "spring.cloud.kubernetes.client." };
29+
private static final String API_VERSION = "apiVersion";
30+
private static final String CA_CERT_FILE = "caCertFile";
31+
private static final String CA_CERT_DATA = "caCertData";
32+
private static final String CLIENT_CERT_FILE = "clientCertFile";
33+
private static final String CLIENT_CERT_DATA = "clientCertData";
34+
private static final String CLIENT_KEY_FILE = "clientKeyFile";
35+
private static final String CLIENT_KEY_DATA = "clientKeyData";
36+
private static final String CLIENT_KEY_ALGO = "clientKeyAlgo";
37+
private static final String CLIENT_KEY_PASSPHRASE = "clientKeyPassphrase";
38+
private static final String CONNECTION_TIMEOUT = "connectionTimeout";
39+
private static final String HTTP_PROXY = "httpProxy";
40+
private static final String HTTPS_PROXY = "httpsProxy";
41+
private static final String LOGGING_INTERVAL = "loggingInterval";
42+
private static final String MASTER_URL = "masterUrl";
43+
private static final String NAMESPACE = "namespace";
44+
private static final String NO_PROXY = "noProxy";
45+
private static final String PASSWORD = "password";
46+
private static final String PROXY_USERNAME = "proxyUsername";
47+
private static final String PROXY_PASSWORD = "proxyPassword";
48+
private static final String REQUEST_TIMEOUT = "requestTimeout";
49+
private static final String TRUST_CERTS = "trustCerts";
50+
private static final String USERNAME = "username";
51+
private static final String WATCH_RECONNECT_INTERVAL = "watchReconnectInterval";
52+
private static final String WATCH_RECONNECT_LIMIT = "watchReconnectLimit";
53+
54+
private final PropertiesUtil props = PropertiesUtil.getProperties();
55+
private final Config base;
56+
57+
public ClientProperties(final Config base) {
58+
this.base = base;
59+
}
60+
61+
public String getApiVersion() {
62+
return props.getStringProperty(PREFIXES, API_VERSION, base::getApiVersion);
63+
}
64+
65+
public String getCaCertFile() {
66+
return props.getStringProperty(PREFIXES, CA_CERT_FILE, base::getCaCertFile);
67+
}
68+
69+
public String getCaCertData() {
70+
return props.getStringProperty(PREFIXES, CA_CERT_DATA, base::getCaCertData);
71+
}
72+
73+
public String getClientCertFile() {
74+
return props.getStringProperty(PREFIXES, CLIENT_CERT_FILE, base::getClientCertFile);
75+
}
76+
77+
public String getClientCertData() {
78+
return props.getStringProperty(PREFIXES, CLIENT_CERT_DATA, base::getClientCertData);
79+
}
80+
81+
public String getClientKeyFile() {
82+
return props.getStringProperty(PREFIXES, CLIENT_KEY_FILE, base::getClientKeyFile);
83+
}
84+
85+
public String getClientKeyData() {
86+
return props.getStringProperty(PREFIXES, CLIENT_KEY_DATA, base::getClientKeyData);
87+
}
88+
89+
public String getClientKeyAlgo() {
90+
return props.getStringProperty(PREFIXES, CLIENT_KEY_ALGO, base::getClientKeyAlgo);
91+
}
92+
93+
public String getClientKeyPassphrase() {
94+
return props.getStringProperty(PREFIXES, CLIENT_KEY_PASSPHRASE, base::getClientKeyPassphrase);
95+
}
96+
97+
public int getConnectionTimeout() {
98+
final Duration timeout = props.getDurationProperty(PREFIXES, CONNECTION_TIMEOUT, null);
99+
if (timeout != null) {
100+
return (int) timeout.toMillis();
101+
}
102+
return base.getConnectionTimeout();
103+
}
104+
105+
public String getHttpProxy() {
106+
return props.getStringProperty(PREFIXES, HTTP_PROXY, base::getHttpProxy);
107+
}
108+
109+
public String getHttpsProxy() {
110+
return props.getStringProperty(PREFIXES, HTTPS_PROXY, base::getHttpsProxy);
111+
}
112+
113+
public int getLoggingInterval() {
114+
final Duration interval = props.getDurationProperty(PREFIXES, LOGGING_INTERVAL, null);
115+
if (interval != null) {
116+
return (int) interval.toMillis();
117+
}
118+
return base.getLoggingInterval();
119+
}
120+
121+
public String getMasterUrl() {
122+
return props.getStringProperty(PREFIXES, MASTER_URL, base::getMasterUrl);
123+
}
124+
125+
public String getNamespace() {
126+
return props.getStringProperty(PREFIXES, NAMESPACE, base::getNamespace);
127+
}
128+
129+
public String[] getNoProxy() {
130+
final String result = props.getStringProperty(PREFIXES, NO_PROXY, null);
131+
if (result != null) {
132+
return result.replace("\\s", "").split(",");
133+
}
134+
return base.getNoProxy();
135+
}
136+
137+
public String getPassword() {
138+
return props.getStringProperty(PREFIXES, PASSWORD, base::getPassword);
139+
}
140+
141+
public String getProxyUsername() {
142+
return props.getStringProperty(PREFIXES, PROXY_USERNAME, base::getProxyUsername);
143+
}
144+
145+
public String getProxyPassword() {
146+
return props.getStringProperty(PREFIXES, PROXY_PASSWORD, base::getProxyPassword);
147+
}
148+
149+
public int getRequestTimeout() {
150+
final Duration interval = props.getDurationProperty(PREFIXES, REQUEST_TIMEOUT, null);
151+
if (interval != null) {
152+
return (int) interval.toMillis();
153+
}
154+
return base.getRequestTimeout();
155+
}
156+
157+
public Boolean isTrustCerts() {
158+
return props.getBooleanProperty(PREFIXES, TRUST_CERTS, base::isTrustCerts);
159+
}
160+
161+
public String getUsername() {
162+
return props.getStringProperty(PREFIXES, USERNAME, base::getUsername);
163+
}
164+
165+
public int getWatchReconnectInterval() {
166+
final Duration interval = props.getDurationProperty(PREFIXES, WATCH_RECONNECT_INTERVAL, null);
167+
if (interval != null) {
168+
return (int) interval.toMillis();
169+
}
170+
return base.getWatchReconnectInterval();
171+
}
172+
173+
public int getWatchReconnectLimit() {
174+
final Duration interval = props.getDurationProperty(PREFIXES, WATCH_RECONNECT_LIMIT, null);
175+
if (interval != null) {
176+
return (int) interval.toMillis();
177+
}
178+
return base.getWatchReconnectLimit();
179+
}
180+
}

0 commit comments

Comments
 (0)