Skip to content
Merged
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
14 changes: 10 additions & 4 deletions jpos/src/main/java/org/jpos/iso/ISOServer.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import java.net.SocketException;
import java.net.UnknownHostException;
import java.time.Duration;
import java.time.Instant;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Semaphore;
Expand Down Expand Up @@ -334,15 +335,20 @@ public void run() {
setChanged ();
notifyObservers ();
UUID sessionUUID = uuid;
String sessionInfo = "";
String endpoint = null;
String host = null;
int remotePort = 0;
int localPort = 0;
Instant start = Instant.now();
if (channel instanceof BaseChannel baseChannel) {
Socket socket = baseChannel.getSocket ();
sessionInfo = socket.toString();
host = socket.getInetAddress().getHostAddress();
remotePort = socket.getPort();
localPort = socket.getLocalPort();
sessionUUID = getSocketUUID(socket);
endpoint = baseChannel.toEndpoint(socket);
LogEvent ev = createSessionEvent(sessionUUID, endpoint)
.add(new SessionStart(getActiveConnections(), permitsCount, sessionInfo)
.add(new SessionStart(getActiveConnections(), permitsCount, host, remotePort, localPort)
);
if (!checkPermission (socket, ev))
return;
Expand Down Expand Up @@ -387,7 +393,7 @@ public void run() {
fireEvent(new ISOServerClientDisconnectEvent(ISOServer.this, channel));
}
Logger.log(createSessionEvent(sessionUUID, endpoint)
.add(new SessionEnd(getActiveConnections(), permitsCount, sessionInfo)
.add(new SessionEnd(getActiveConnections(), permitsCount, host, remotePort, localPort, Duration.between(start, Instant.now()))
)
);
}
Expand Down
20 changes: 18 additions & 2 deletions jpos/src/main/java/org/jpos/log/evt/SessionEnd.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,29 @@

package org.jpos.log.evt;

import com.fasterxml.jackson.annotation.JsonInclude;
import org.jpos.log.AuditLogEvent;

import java.time.Duration;

/**
* Audit event recorded when a server session terminates.
*
* <p>Field names mirror {@link Connect} and {@link Disconnect} so viewers can
* render channel and server sessions with one template.</p>
*
* @param connections active connection count after this session ended
* @param permits remaining session permits
* @param info free-form description of the closing session
* @param host remote address, or {@code null} when the channel exposes no socket
* @param remotePort remote port
* @param localPort local port the session was accepted on
* @param duration session length, from accept to close
*/
public record SessionEnd(int connections, int permits, String info) implements AuditLogEvent { }
public record SessionEnd(
int connections,
int permits,
@JsonInclude(JsonInclude.Include.NON_NULL) String host,
int remotePort,
int localPort,
Duration duration
) implements AuditLogEvent { }
35 changes: 15 additions & 20 deletions jpos/src/main/java/org/jpos/log/evt/SessionStart.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,32 +16,27 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package org.jpos.log.evt;/*
* jPOS Project [http://jpos.org]
* Copyright (C) 2000-2010 Alejandro P. Revilla
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.jpos.log.evt;

import com.fasterxml.jackson.annotation.JsonInclude;
import org.jpos.log.AuditLogEvent;

/**
* Audit event recorded when a server session opens.
*
* <p>Field names mirror {@link Connect} and {@link Disconnect} so viewers can
* render channel and server sessions with one template.</p>
*
* @param connections active connection count after this session started
* @param permits remaining session permits
* @param info free-form description of the opening session
* @param host remote address, or {@code null} when the channel exposes no socket
* @param remotePort remote port
* @param localPort local port the session was accepted on
*/
public record SessionStart(int connections, int permits, String info) implements AuditLogEvent {
}
public record SessionStart(
int connections,
int permits,
@JsonInclude(JsonInclude.Include.NON_NULL) String host,
int remotePort,
int localPort
) implements AuditLogEvent { }
15 changes: 15 additions & 0 deletions jpos/src/test/java/org/jpos/iso/ISOServerTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,21 @@ public void testSessionEventsUseStableRealmAndDynamicTags() throws Exception {
assertEquals(org.jpos.util.Kind.ISO_SESSION, sessionEvent.getTag(), "sessionEvent.getTag()");
assertTrue(sessionEvent.getTags().containsKey("session"), "sessionEvent.getTags().containsKey(session)");
assertTrue(sessionEvent.getTags().containsKey("endpoint"), "sessionEvent.getTags().containsKey(endpoint)");
org.jpos.log.evt.SessionStart start = sessionEvent.getPayLoad().stream()
.filter(p -> p instanceof org.jpos.log.evt.SessionStart)
.map(p -> (org.jpos.log.evt.SessionStart) p)
.findFirst().orElseThrow();
assertEquals("127.0.0.1", start.host(), "start.host()");
assertEquals(port, start.localPort(), "start.localPort()");
assertTrue(start.remotePort() > 0, "start.remotePort()");
org.jpos.log.evt.SessionEnd end = events.stream()
.flatMap(ev -> ev.getPayLoad().stream())
.filter(p -> p instanceof org.jpos.log.evt.SessionEnd)
.map(p -> (org.jpos.log.evt.SessionEnd) p)
.findFirst().orElseThrow();
assertEquals(start.remotePort(), end.remotePort(), "end.remotePort()");
assertEquals(port, end.localPort(), "end.localPort()");
assertTrue(end.duration() != null && !end.duration().isNegative(), "end.duration()");
}
} finally {
server.shutdown();
Expand Down
6 changes: 3 additions & 3 deletions jpos/src/test/java/org/jpos/util/KindTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ void kindOfTypeFollowsTheUmbrella() {
assertEquals(Kind.LIFECYCLE, Kind.kindOf("license"));
assertEquals(Kind.DEPLOY, Kind.kindOf("undeploy"));
assertEquals(Kind.ERROR, Kind.kindOf("throwable"));
assertEquals(Kind.ISO_SESSION, Kind.kindOf(new SessionStart(1, 10, "x")));
assertEquals(Kind.ISO_SESSION, Kind.kindOf(new SessionStart(1, 10, "127.0.0.1", 4321, 8000)));
}

@Test
Expand Down Expand Up @@ -163,11 +163,11 @@ void logLevelConstantsAreUnchangedAndReferenceKind() {
@Test
void createEventUsesTheImpliedKindAndDefaultStaysInfo() {
Log log = new Log(new Logger(), "test");
LogEvent evt = log.createEvent(new SessionStart(1, 10, "x"));
LogEvent evt = log.createEvent(new SessionStart(1, 10, "127.0.0.1", 4321, 8000));
assertEquals(Kind.ISO_SESSION, evt.getTag());
assertEquals(1, evt.getPayLoad().size());
assertEquals(Kind.INFO, log.createEvent(new ProfilerEvt(0L, List.of())).getTag());
assertEquals(Kind.INFO, new LogEvent().getTag());
assertEquals(Kind.ISO_SESSION, new LogEvent(log, new SessionStart(1, 10, "x")).getTag());
assertEquals(Kind.ISO_SESSION, new LogEvent(log, new SessionStart(1, 10, "127.0.0.1", 4321, 8000)).getTag());
}
}