Skip to content

Commit

Permalink
Add monitoring page
Browse files Browse the repository at this point in the history
  • Loading branch information
Tobias Hafner committed Apr 8, 2024
1 parent 3918305 commit 8292e5b
Show file tree
Hide file tree
Showing 6 changed files with 236 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,12 @@
import java.security.SecureRandom;
import java.util.Base64;
import java.util.List;
import java.util.Map.Entry;
import java.util.Optional;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Stream;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.polypheny.db.catalog.Catalog;
Expand All @@ -44,14 +46,15 @@ public class ClientManager {
@Getter
private long heartbeatInterval;

private final ConcurrentHashMap<String, PIClient> openConnections;
private final ConcurrentHashMap<String, PIClient> clients;
private final Authenticator authenticator;
private final TransactionManager transactionManager;
private Timer cleanupTimer;
private final MonitoringPage monitoringPage;


public ClientManager( PIPlugin.ProtoInterface protoInterface ) {
this.openConnections = new ConcurrentHashMap<>();
this.clients = new ConcurrentHashMap<>();
this.authenticator = protoInterface.getAuthenticator();
this.transactionManager = protoInterface.getTransactionManager();
if ( protoInterface.isRequiresHeartbeat() ) {
Expand All @@ -60,13 +63,15 @@ public ClientManager( PIPlugin.ProtoInterface protoInterface ) {
cleanupTimer.schedule( createNewCleanupTask(), 0, heartbeatInterval + HEARTBEAT_TOLERANCE );
}
this.heartbeatInterval = 0;
this.monitoringPage = protoInterface.getMonitoringPage();
monitoringPage.setClientManager( this );
}


public void unregisterConnection( PIClient client ) {
synchronized ( client ) {
client.prepareForDisposal();
openConnections.remove( client.getClientUUID() );
clients.remove( client.getClientUUID() );
}
}

Expand Down Expand Up @@ -102,16 +107,26 @@ public String registerConnection( ConnectionRequest connectionRequest, Transport
user,
transactionManager,
namespace,
monitoringPage,
isAutocommit
);
openConnections.put( uuid, client );
clients.put( uuid, client );
if ( log.isTraceEnabled() ) {
log.trace( "proto-interface established connection to user {}.", uuid );
}
return uuid;
}


public Stream<Entry<String, PIClient>> getClients() {
return clients.entrySet().stream();
}

public int getClientCount() {
return clients.size();
}


private LogicalNamespace getNamespaceOrDefault( ConnectionRequest connectionRequest ) {
String namespaceName = PropertyUtils.DEFAULT_NAMESPACE_NAME;
if ( connectionRequest.hasConnectionProperties() && connectionRequest.getConnectionProperties().hasNamespaceName() ) {
Expand All @@ -135,10 +150,10 @@ private boolean getAutocommitOrDefault( ConnectionRequest connectionRequest ) {


public PIClient getClient( String clientUUID ) throws PIServiceException {
if ( !openConnections.containsKey( clientUUID ) ) {
if ( !clients.containsKey( clientUUID ) ) {
throw new PIServiceException( "Client not registered! Has the server been restarted in the meantime?" );
}
return openConnections.get( clientUUID );
return clients.get( clientUUID );
}


Expand All @@ -154,14 +169,9 @@ public void run() {


private void unregisterInactiveClients() {
List<PIClient> inactiveClients = openConnections.values().stream()
List<PIClient> inactiveClients = clients.values().stream()
.filter( c -> !c.returnAndResetIsActive() ).toList();
inactiveClients.forEach( this::unregisterConnection );
}


private boolean isConnected( String clientUUID ) {
return openConnections.containsKey( clientUUID );
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
/*
* Copyright 2019-2024 The Polypheny Project
*
* 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 org.polypheny.db.protointerface;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import lombok.Setter;
import org.polypheny.db.information.InformationGroup;
import org.polypheny.db.information.InformationManager;
import org.polypheny.db.information.InformationPage;
import org.polypheny.db.information.InformationTable;
import org.polypheny.db.protointerface.statements.StatementManager;

public class MonitoringPage {

@Setter
private ClientManager clientManager;

private Set<StatementManager> statementManagers;
private final InformationPage informationPage;
private final InformationGroup interfaceGroup;
private final InformationTable statementsTable;
private final InformationTable connectionsTable;

private final InformationGroup connectionsGroup;
private final InformationTable connectionListTable;


public MonitoringPage( String uniqueName, String description ) {
statementManagers = new HashSet<>();

InformationManager informationManager = InformationManager.getInstance();

informationPage = new InformationPage( uniqueName, description )
.fullWidth()
.setLabel( "Interfaces" );
interfaceGroup = new InformationGroup( informationPage, "Interface Statistics" );

informationManager.addPage( informationPage );
informationManager.addGroup( interfaceGroup );

statementsTable = new InformationTable( interfaceGroup, Arrays.asList( "Attribute", "Value" ) );
statementsTable.setOrder( 1 );
informationManager.registerInformation( statementsTable );

connectionsTable = new InformationTable( interfaceGroup, Arrays.asList( "Attribute", "Value" ) );
connectionsTable.setOrder( 2 );
informationManager.registerInformation( connectionsTable );

connectionsGroup = new InformationGroup( informationPage, "Connections" );
informationManager.addGroup( connectionsGroup );
connectionListTable = new InformationTable( connectionsGroup,
Arrays.asList( "UUID", "TX", "Auto Commit", "Default Namespace" ) );
connectionListTable.setOrder( 3 );
informationManager.registerInformation( connectionListTable );

informationPage.setRefreshFunction( this::update );
}


public void update() {
connectionsTable.reset();
connectionsTable.addRow( "Open Connections", clientManager.getClientCount() );

statementsTable.reset();
AtomicInteger statementCount = new AtomicInteger();
statementManagers.forEach(m -> statementCount.addAndGet( m.openStatementCount() ) );
statementsTable.addRow( "Open Statements", statementCount.get() );

connectionListTable.reset();
clientManager.getClients().forEach( this::addClientEntry );
}


private void addClientEntry( Entry<String, PIClient> clientEntry ) {
String uuid = clientEntry.getKey();
PIClient client = clientEntry.getValue();
String txId = "-";
if ( !client.hasNoTransaction() ) {
txId = String.valueOf( client.getCurrentOrCreateNewTransaction().getId() );
}
connectionListTable.addRow(
uuid,
txId,
client.isAutoCommit(),
client.getNamespace()
);
}


public void addStatementManager( StatementManager statementManager ) {
statementManagers.add( statementManager );
}


public void removeStatementManager( StatementManager statementManager ) {
statementManagers.remove( statementManager );
}


public void remove() {
InformationManager im = InformationManager.getInstance();
im.removeInformation( connectionsTable );
im.removeInformation( statementsTable );
im.removeInformation( connectionListTable );
im.removeGroup( interfaceGroup );
im.removePage( informationPage );
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,16 @@ public class PIClient {
@Setter
private LogicalNamespace namespace;
private boolean isActive;
@Getter
private MonitoringPage monitoringPage;


public PIClient(
String clientUUID,
LogicalUser catalogUser,
TransactionManager transactionManager,
LogicalNamespace namespace,
MonitoringPage monitoringPage,
boolean isAutoCommit ) {
this.statementManager = new StatementManager( this );
this.PIClientInfoProperties = new PIClientInfoProperties();
Expand All @@ -61,6 +64,8 @@ public PIClient(
this.transactionManager = transactionManager;
this.isAutoCommit = isAutoCommit;
this.isActive = true;
this.monitoringPage = monitoringPage;
monitoringPage.addStatementManager( statementManager );
}


Expand Down Expand Up @@ -134,6 +139,7 @@ public void prepareForDisposal() {
if ( !hasNoTransaction() ) {
rollbackCurrentTransaction();
}
monitoringPage.removeStatementManager( statementManager );
}


Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/*
* Copyright 2019-2024 The Polypheny Project
*
* 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 org.polypheny.db.protointerface;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;

public class PIPerformanceLogger {
private BufferedWriter writer;
private static final String PATH = System.getProperty( "user.home" ) + "/uni_basel/master_project/benchmarking/";

// Method to open a file. If the file exists, it will be overwritten.
public void openFile(String fileName) {
try {
// FileWriter is set to false to overwrite the file if it exists
writer = new BufferedWriter(new FileWriter(PATH + fileName, true));
} catch ( IOException e) {
e.printStackTrace();
}
}

// Method to write a line to the file
public void write(String line) {
try {
if (writer != null) {
writer.write(line + ",");
} else {
System.out.println("Error: File is not opened yet.");
}
} catch (IOException e) {
e.printStackTrace();
}
}

public void writeNewLine() {
try {
if (writer != null) {
writer.newLine();
} else {
System.out.println("Error: File is not opened yet.");
}
} catch (IOException e) {
e.printStackTrace();
}
}

// Method to close the file
public void closeFile() {
try {
if (writer != null) {
writer.close();
} else {
System.out.println("Error: File is not opened or already closed.");
}
} catch (IOException e) {
e.printStackTrace();
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ public static class ProtoInterface extends QueryInterface implements PropertyCha
@Getter
private ClientManager clientManager;
private PIServer protoInterfaceServer;
@Getter
private MonitoringPage monitoringPage;


enum Transport {
Expand All @@ -104,6 +106,7 @@ private ProtoInterface( TransactionManager transactionManager, Authenticator aut
this.requiresHeartbeat = false;
this.heartbeatInterval = 0;
}
this.monitoringPage = new MonitoringPage( uniqueName, INTERFACE_NAME );
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -233,4 +233,8 @@ public boolean isSupportedLanguage( String statementLanguageName ) {
.contains( statementLanguageName );
}

public int openStatementCount() {
return openStatements.size();
}

}

0 comments on commit 8292e5b

Please sign in to comment.