Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
3 changes: 3 additions & 0 deletions README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ An example configuration file is available in `conf/examples/`, which removes th

|verbose |Log detailed information about an MQTT event | false
|payload |Log the payload of a message | true
|passwordinverbose |Log the password when verbose is `true` | true
|===

Normally, events only log important information.
Expand All @@ -83,6 +84,8 @@ CAUTION: use `verbose=true` very carefully as it will flood your log immediately

Set the `payload` property to `false` if you want to suppress logging payloads (i.e. for publish-received, publish-send, and will messages).

Set the `passwordinverbose` property to `false` to prevent logging the password, even when verbose is `true`.

== First Steps

Connect with an {hivemq-blog-tools}[MQTT client] of your choice.
Expand Down
1 change: 1 addition & 0 deletions src/hivemq-extension/conf/examples/config.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
<!--General settings-->
<verbose>false</verbose>
<payload>true</payload>
<passwordinverbose>true</passwordinverbose>

<!--Event settings-->
<publish-received>false</publish-received>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
/*
* Copyright 2019-present HiveMQ GmbH
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hivemq.extensions.log;

import com.hivemq.client.mqtt.datatypes.MqttQos;
import com.hivemq.client.mqtt.mqtt5.Mqtt5BlockingClient;
import com.hivemq.client.mqtt.mqtt5.Mqtt5Client;
import com.hivemq.client.mqtt.mqtt5.message.publish.Mqtt5PayloadFormatIndicator;
import io.github.sgtsilvio.gradle.oci.junit.jupiter.OciImages;
import org.jetbrains.annotations.NotNull;
import org.junit.jupiter.api.Test;
import org.testcontainers.hivemq.HiveMQContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import org.testcontainers.utility.MountableFile;

import java.nio.charset.StandardCharsets;

import static org.awaitility.Awaitility.await;

/**
* @since 1.1.3
*/
@Testcontainers
public class FullConfigNoPasswordInVerboseIT {

@Container
final @NotNull HiveMQContainer hivemq =
new HiveMQContainer(OciImages.getImageName("hivemq/extensions/hivemq-mqtt-message-log-extension")
.asCompatibleSubstituteFor("hivemq/hivemq4")) //
.withCopyToContainer(MountableFile.forClasspathResource("fullConfigNoPasswordInVerbose.properties"),
"/opt/hivemq/extensions/hivemq-mqtt-message-log-extension/mqttMessageLog.properties")
.withLogConsumer(outputFrame -> System.out.print("HiveMQ: " + outputFrame.getUtf8String()));

@Test
void test() {
final Mqtt5BlockingClient client = Mqtt5Client.builder()
.identifier("test-client")
.serverHost(hivemq.getHost())
.serverPort(hivemq.getMqttPort())
.buildBlocking();

client.connectWith()
.willPublish()
.topic("will")
.qos(MqttQos.EXACTLY_ONCE)
.payload("willPayload".getBytes(StandardCharsets.UTF_8))
.contentType("text/plain")
.correlationData("willCorrelationData".getBytes(StandardCharsets.UTF_8))
.payloadFormatIndicator(Mqtt5PayloadFormatIndicator.UTF_8)
.responseTopic("willResponse")
.retain(false)
.messageExpiryInterval(10_000)
.userProperties()
.add("willProperty", "willValue")
.applyUserProperties()
.delayInterval(50_000)
.applyWillPublish()
.send();
await().until(() -> hivemq.getLogs()
.contains(
"Received CONNECT from client 'test-client': Protocol version: 'V_5', Clean Start: 'true', Session Expiry Interval: '0', Keep Alive: '60', Maximum Packet Size: '268435460', Receive Maximum: '65535', Topic Alias Maximum: '0', Request Problem Information: 'true', Request Response Information: 'false', Username: 'null', Auth Method: 'null', Auth Data (Base64): 'null', User Properties: 'null', Will: { Topic: 'will', Payload: 'willPayload', QoS: '2', Retained: 'false', Message Expiry Interval: '10000', Duplicate Delivery: 'false', Correlation Data: 'willCorrelationData', Response Topic: 'willResponse', Content Type: 'text/plain', Payload Format Indicator: 'UTF_8', Subscription Identifiers: '[]', User Properties: [Name: 'willProperty', Value: 'willValue'], Will Delay: '50000' }"));
await().until(() -> hivemq.getLogs()
.contains(
"Sent CONNACK to client 'test-client': Reason Code: 'SUCCESS', Session Present: 'false', Session Expiry Interval: 'null', Assigned ClientId 'null', Maximum QoS: 'EXACTLY_ONCE', Maximum Packet Size: '268435460', Receive Maximum: '10', Topic Alias Maximum: '5', Reason String: 'null', Response Information: 'null', Server Keep Alive: 'null', Server Reference: 'null', Shared Subscription Available: 'true', Wildcards Available: 'true', Retain Available: 'true', Subscription Identifiers Available: 'true', Auth Method: 'null', Auth Data (Base64): 'null', User Properties: 'null'"));

client.subscribeWith().topicFilter("#").send();
await().until(() -> hivemq.getLogs()
.contains(
"Received SUBSCRIBE from client 'test-client': Topics: { [Topic: '#', QoS: '2', Retain As Published: 'false', No Local: 'false', Retain Handling: 'SEND'] }, Subscription Identifier: '1', User Properties: 'null'"));
await().until(() -> hivemq.getLogs()
.contains(
"Sent SUBACK to client 'test-client': Suback Reason Codes: { [Reason Code: 'GRANTED_QOS_2'] }, Reason String: 'null', User Properties: 'null'"));

client.publishWith()
.topic("publish")
.qos(MqttQos.EXACTLY_ONCE)
.payload("payload1".getBytes(StandardCharsets.UTF_8))
.contentType("text/plain")
.correlationData("willCorrelationData".getBytes(StandardCharsets.UTF_8))
.payloadFormatIndicator(Mqtt5PayloadFormatIndicator.UTF_8)
.responseTopic("publishResponse")
.retain(false)
.messageExpiryInterval(10_000)
.userProperties()
.add("publishProperty", "publishValue")
.applyUserProperties()
.send();
await().until(() -> hivemq.getLogs()
.contains(
"Received PUBLISH from client 'test-client' for topic 'publish': Payload: 'payload1', QoS: '2', Retained: 'false', Message Expiry Interval: '10000', Duplicate Delivery: 'false', Correlation Data: 'willCorrelationData', Response Topic: 'publishResponse', Content Type: 'text/plain', Payload Format Indicator: 'UTF_8', Subscription Identifiers: '[]', User Properties: [Name: 'publishProperty', Value: 'publishValue']"));
await().until(() -> hivemq.getLogs()
.contains(
"Sent PUBREC to client 'test-client': Reason Code: 'SUCCESS', Reason String: 'null', User Properties: 'null'"));
await().until(() -> hivemq.getLogs()
.contains(
"Received PUBREL from client 'test-client': Reason Code: 'SUCCESS', Reason String: 'null', User Properties: 'null'"));
await().until(() -> hivemq.getLogs()
.contains(
"Sent PUBCOMP to client 'test-client': Reason Code: 'SUCCESS', Reason String: 'null', User Properties: 'null'"));

await().until(() -> hivemq.getLogs()
.contains(
"Sent PUBLISH to client 'test-client' on topic 'publish': Payload: 'payload1', QoS: '2', Retained: 'false', Message Expiry Interval: '10000', Duplicate Delivery: 'false', Correlation Data: 'willCorrelationData', Response Topic: 'publishResponse', Content Type: 'text/plain', Payload Format Indicator: 'UTF_8', Subscription Identifiers: '[1]', User Properties: [Name: 'publishProperty', Value: 'publishValue']"));
await().until(() -> hivemq.getLogs()
.contains(
"Received PUBREC from client 'test-client': Reason Code: 'SUCCESS', Reason String: 'null', User Properties: 'null'"));
await().until(() -> hivemq.getLogs()
.contains(
"Sent PUBREL to client 'test-client': Reason Code: 'SUCCESS', Reason String: 'null', User Properties: 'null'"));
await().until(() -> hivemq.getLogs()
.contains(
"Received PUBCOMP from client 'test-client': Reason Code: 'SUCCESS', Reason String: 'null', User Properties: 'null'"));

client.publishWith()
.topic("publish")
.qos(MqttQos.AT_LEAST_ONCE)
.payload("payload2".getBytes(StandardCharsets.UTF_8))
.contentType("text/plain")
.correlationData("willCorrelationData".getBytes(StandardCharsets.UTF_8))
.payloadFormatIndicator(Mqtt5PayloadFormatIndicator.UTF_8)
.responseTopic("publishResponse")
.retain(false)
.messageExpiryInterval(10_000)
.userProperties()
.add("publishProperty", "publishValue")
.applyUserProperties()
.send();
await().until(() -> hivemq.getLogs()
.contains(
"Received PUBLISH from client 'test-client' for topic 'publish': Payload: 'payload2', QoS: '1', Retained: 'false', Message Expiry Interval: '10000', Duplicate Delivery: 'false', Correlation Data: 'willCorrelationData', Response Topic: 'publishResponse', Content Type: 'text/plain', Payload Format Indicator: 'UTF_8', Subscription Identifiers: '[]', User Properties: [Name: 'publishProperty', Value: 'publishValue']"));
await().until(() -> hivemq.getLogs()
.contains(
"Sent PUBACK to client 'test-client': Reason Code: 'SUCCESS', Reason String: 'null', User Properties: 'null'"));
await().until(() -> hivemq.getLogs()
.contains(
"Sent PUBLISH to client 'test-client' on topic 'publish': Payload: 'payload2', QoS: '1', Retained: 'false', Message Expiry Interval: '10000', Duplicate Delivery: 'false', Correlation Data: 'willCorrelationData', Response Topic: 'publishResponse', Content Type: 'text/plain', Payload Format Indicator: 'UTF_8', Subscription Identifiers: '[1]', User Properties: [Name: 'publishProperty', Value: 'publishValue']"));
await().until(() -> hivemq.getLogs()
.contains(
"Received PUBACK from client 'test-client': Reason Code: 'SUCCESS', Reason String: 'null', User Properties: 'null'"));

client.unsubscribeWith().topicFilter("#").send();
await().until(() -> hivemq.getLogs()
.contains(
"Received UNSUBSCRIBE from client 'test-client': Topics: { [Topic: '#'] }, User Properties: 'null'"));
await().until(() -> hivemq.getLogs()
.contains(
"Sent UNSUBACK to client 'test-client': Unsuback Reason Codes: { [Reason Code: 'SUCCESS'] }, Reason String: 'null', User Properties: 'null'"));

client.disconnect();
await().until(() -> hivemq.getLogs()
.contains(
"Received DISCONNECT from client 'test-client': Reason Code: 'NORMAL_DISCONNECTION', Reason String: 'null', Server Reference: 'null', Session Expiry: 'null', User Properties: 'null'"));
}
}
Loading