1. Overview
Aspectow AppMon is a lightweight real-time monitoring solution for applications built on the Aspectran framework. Designed to minimize impact on application performance, it allows operators and developers to visually observe various runtime events, logs, and system metrics in real time via a web UI.
It can run embedded within Aspectow Console in an integrated control environment, or deployed as a standalone solution without Console for lightweight monitoring operations.
2. Key Features
- Real-time Monitoring: Streams data generated on the server in real time via WebSocket or Long-Polling to display on the UI.
- Lightweight & Easy Integration: Easily registered as an Aspectran Bean in target applications, utilizing minimal resources to prevent performance degradation.
- Dynamic Monitoring: Leverages Aspectran’s AOP capabilities to dynamically trace transaction (
Activity) executions and measure performance without code modifications. - Always-On User Tracking & Geolocation: Automatically captures client IP addresses and resolves country codes upon session creation without business code modification.
- Non-intrusive Username Resolution: Flexibly extracts usernames from complex session objects via declarative property expressions (
usernameAttribute) or customSessionUserResolverextensions. - Diverse Data Sources:
- Events: Tracks and counts core application events such as HTTP request handling and session creation/destruction.
- Metrics: Collects diverse system metrics including JVM heap memory usage (
HeapMemoryUsageReader), Undertow and Netty thread pool status (UndertowThreadPoolMetricsReader,NettyThreadPoolMetricsReader), and HikariCP connection pool metrics (HikariPoolMBeanReader). - Logs: Streams real-time tailing of specified application and access log files on the UI.
- Data Persistence: Periodically saves event counter metrics to an embedded H2 database or external RDBMS to preserve statistical data across application restarts.
- Flexible APON Configuration: Defines nodes and monitoring target applications flexibly using APON (Aspectran Parameter Object Notation) configuration files.
3. Core Architecture & 3-Tier Hierarchy
Aspectow AppMon utilizes a 3-tier hierarchy—Group (Server Group) - Node (Server Node) - App (Application)—for distributed monitoring identification.
Key Engine Components
- AppMonManager: The core engine managing the overall lifecycle and configuration of AppMon.
- Exporter: Responsible for collecting data from specific data sources (logs, metrics, events).
- Reader: Implements concrete data collection methods for
Exporter(e.g., querying JVM metrics via JMX, reading log files from filesystem).
- Reader: Implements concrete data collection methods for
- UserTrackingListener: An always-on session listener that injects client IP addresses (
user.ipAddress) and resolved country codes (user.countryCode) into session attributes upon creation. - PersistManager: Handles periodic persistence of collected counter metrics to the database.
- CounterPersistSchedule: Scheduled task executing periodically to store counter data to the DB.
- ExportService: Manages communication with client web UIs, transmitting collected data via WebSocket or Polling.
- Activity (Front/Backend): Acts as controllers handling HTTP requests from web UIs or external agents.
4. Session Monitoring & User Tracking Architecture
AppMon provides an advanced session monitoring architecture combining always-on user tracking and on-demand live event broadcasting.
4.1. Lifecycle Separation: Always-On vs. On-Demand
- Always-On User Tracking (
UserTrackingListener):- Registered permanently to the target context’s (
contextName)SessionManagerduringSessionEventReader.init()at server startup. - Operates 24/7 regardless of whether an administrator is connected to the AppMon UI, ensuring that all created sessions have client IP addresses and country codes populated.
- Guarantees that full active session inquiries (
getAllActiveSessions) always display complete client location details without omissions. - Built-in duplicate registration guard (
registeredTrackingTargets) ensures that even if multipleapps reference the same target (tow.server/demoornetty.server/demo), the listener is registered exactly once.
- Registered permanently to the target context’s (
- On-Demand Live Broadcasting (
SessionEventReadingListener):- Registered only when an administrator subscribes to a specific app’s dashboard and unregistered when subscriber count drops to zero (
stop()), minimizing runtime resource overhead.
- Registered only when an administrator subscribes to a specific app’s dashboard and unregistered when subscriber count drops to zero (
4.2. Country Code Resolution (IPCountryResolver)
AppMon resolves ISO 2-letter country codes (e.g., KR, US, JP) from client IP addresses using the pluggable IPCountryResolver interface:
package com.aspectran.aspectow.appmon.common.support;
public interface IPCountryResolver {
String resolveCountryCode(String ipAddress, Locale locale);
default String resolveCountryCode(String ipAddress) { ... }
}
Implementations integrating with KISA WHOIS OpenAPI (WhoisIPCountryResolver) or MaxMind GeoIP database registered as Beans in appmon-rules.xml enable automatic querying and injection into user.countryCode upon session creation.
4.3. Non-intrusive Username Extraction (usernameAttribute & SessionUserResolver)
Production web applications store login details inside custom objects such as UserSession, Account, or Principal rather than simple strings. AppMon supports a 3-tier priority hierarchy to extract usernames without modifying application code:
- Custom Resolver (
userResolver): Preferentially invokesevent.parameters.userResolveror aSessionUserResolverBean/class registered in the context:public interface SessionUserResolver { String resolveUsername(String deploymentName, Session session); } - Declarative Property Path Navigation (
usernameAttribute): Specifying a JavaBean property path (e.g.,user.account.username) automatically traverses nested getters (session.getAttribute("user").getAccount().getUsername()):event: { id: session target: tow.server/jpetstore parameters: { usernameAttribute: user.account.username } } - Default Fallback: Reads the
user.nameattribute configured on the session if present.
4.4. Real-time Authentication State Detection
When a user logs in and an authentication object (e.g., "user") is added or updated in the session, SessionEventReader intercepts attributeAdded / attributeUpdated events and immediately broadcasts a refreshed session event to the AppMon dashboard.
5. Data Persistence Architecture Overview
Aspectow AppMon persistently stores event count metrics in a database to maintain continuous statistics. By default, it uses an embedded H2 database and provides the following primary tables:
appmon_event_count: Stores count metrics aggregated by minute, hour, day, month, and year, queried directly for dashboard visualization charts.appmon_event_count_last: Stores the most recent count state for each event to restore in-memory counters upon application restart, ensuring statistical continuity.
For detailed composite PK schemas and pre-aggregation 3-tier storage architecture, refer to the AppMon Event Count Data Structure and Architecture documentation.
6. Standalone Installation & Configuration Guide (Without Console)
When deploying AppMon standalone on specific application servers without building Console, configuration files are organized under the project’s /config/appmon/ directory.
6.1. Configuration Directory Structure (/config/appmon/)
appmon-config.apon: Main configuration file defining target applications (app), events, metrics, logs, and counter persistence intervals.node-config.apon: Server group (group) and server node (node) definition file.appmon-rules.xml&node-rules.xml: Aspectran XML rule files loading configuration files viaAppMonConfigResolverandNodeConfigResolverand registeringNodeManagerFactoryBean.appmon.db-h2.properties: Property file configuring the embedded H2 DB storage path.
6.2. APON Main Configuration (appmon-config.apon) Example
The appmon-config.apon file defines target applications (app), collected events, metrics, logs, and persistence intervals.
# DB persistence interval (in minutes, e.g., 1 minute)
counterPersistInterval: 1
# Long-Polling configuration for non-WebSocket environments
pollingConfig: {
pollingInterval: 3000 # Polling interval (ms)
sessionTimeout: 30000 # Session expiration (ms)
}
# Target application definition
app: {
id: jpetstore
title: JPetStore Webapp
event: {
id: activity
target: jpetstore
parameters: {
+: /**
}
}
event: {
id: session
target: tow.server/jpetstore
parameters: {
# Declaratively extract username from session object without code changes
usernameAttribute: user.account.username
}
}
metric: {
id: heap
title: Heap Usage
description: Monitors JVM Heap memory usage.
reader: com.aspectran.aspectow.appmon.engine.exporter.metric.jvm.HeapMemoryUsageReader
sampleInterval: 500
}
# When using Undertow server
metric: {
id: undertow-tp
title: Undertow Thread Pool
description: Monitors Undertow worker thread pool resources.
reader: com.aspectran.aspectow.appmon.engine.exporter.metric.undertow.UndertowThreadPoolMetricsReader
target: tow.server
sampleInterval: 500
}
# When using Netty server
# metric: {
# id: netty-tp
# title: Netty Thread Pool
# description: Monitors Netty worker thread pool and concurrent request processing status.
# reader: com.aspectran.aspectow.appmon.engine.exporter.metric.netty.NettyThreadPoolMetricsReader
# target: netty.server
# sampleInterval: 500
# }
log: {
id: app
file: /logs/jpetstore.log
sampleInterval: 300
lastLines: 300
}
}
6.3. Key APON Parameter Specifications
counterPersistInterval: Interval in minutes for saving aggregated event counter data to DB (default: 5 minutes; setting to0disables DB persistence).pollingConfig: Configures Long-Polling connection behavior (pollingInterval,sessionTimeout).app: Individual application unit to monitor.event:id: Event type (activity,session).target: Target context identifier or server context path (tow.server/<contextName>ornetty.server/<contextName>).parameters:- For
activity: Pointcut+/-path filters. - For
session:usernameAttribute(property path, e.g.,user.account.username),userResolver(customSessionUserResolverclass name or Bean ID).
- For
metric:reader(fully qualified class name ofMetricReaderimplementation),parameters(additional arguments).log:file(target log file path for tailing),lastLines(initial line count loaded upon UI access).
Server group (
group) and server node (node) definitions are specified separately innode-config.aponornode-config-gateway.apon.
6.4. Step-by-Step Installation & Operational Guide
Step 1: Define Target Applications (/config/appmon/appmon-config.apon)
Specify target app, event, metric, and log entries inside appmon-config.apon.
Step 2: Define Node Cluster (/config/appmon/node-config.apon)
Define server group (group) and server node (node) inside node-config.apon (or node-config-gateway.apon).
cluster: {
id: appmon-cluster1
mode: direct
}
group: {
id: group1
title: Group 1
}
node: {
id: appmon-node1
group: group1
title: Localhost
endpoint: {
mode: auto
}
}
Step 3: Configure XML Rules (appmon-rules.xml & node-rules.xml)
Specify configuration files using AppMonConfigResolver inside appmon-rules.xml and append appropriate node rules (node-rules.xml):
<!-- Example appmon-rules.xml -->
<aspectran>
<bean class="com.aspectran.aspectow.appmon.engine.config.AppMonConfigResolver">
<properties profile="!prod">
<item name="configLocation">/config/appmon/appmon-config.apon</item>
</properties>
<properties profile="prod">
<item name="configLocation">/config/appmon/appmon-config-prod.apon</item>
</properties>
</bean>
<!-- Optional: Register IP Country Resolver Bean -->
<!-- <bean id="ipCountryResolver" class="com.aspectran.aspectow.demo.root.common.WhoisIPCountryResolver"/> -->
<append file="/config/appmon/node-rules.xml"/>
</aspectran>
In node-rules.xml, load node-config.apon via NodeConfigResolver and register NodeManagerFactoryBean:
<!-- Example node-rules.xml -->
<aspectran>
<bean class="com.aspectran.aspectow.node.config.NodeConfigResolver">
<properties>
<item name="configLocation">/config/appmon/node-config.apon</item>
</properties>
</bean>
<bean id="nodeManager" class="com.aspectran.aspectow.node.manager.NodeManagerFactoryBean" lazyDestroy="true"/>
</aspectran>
Step 4: Database Connection and Profile Configuration (Database & Profile Configuration)
To run standalone AppMon, execution profiles and database connection details must be configured correctly.
- Mandatory Standalone Profile (
appmon.standalone): To run AppMon as an independent solution without Console, specifying theappmon.standaloneprofile is mandatory. - Default Profile & H2 Database: In the default configuration (
aspectran-config.apon),appmon.standaloneand embeddedh2profiles are activated by default, allowing instant development and demo execution without additional DB setups. - RDBMS Switching & Property File Addition: To connect to a database other than
h2(e.g., MariaDB, MySQL, PostgreSQL, Oracle), specify the corresponding DB profile (e.g.,mariadb) and add the matching property file (appmon.db-mariadb.properties) under the project’s/config/appmon/directory.
Standalone AppMon typically runs under the appmon context name, so execution profiles and connection properties are passed via Java System Properties as follows:
# Example of running standalone (appmon.standalone) mode with MariaDB
-Daspectran.profiles.base.appmon=appmon.standalone,mariadb -Dappmon.db-mariadb.url=jdbc:mariadb://127.0.0.1:3306/appmon_db -Dappmon.db-mariadb.username=appmon -Dappmon.db-mariadb.password=your-password
7. Conclusion
Aspectow AppMon can run embedded as an integrated monitoring engine within Aspectow Console, or be easily deployed as a standalone monitoring solution via /config/appmon/ settings as needed to enhance application transparency and observability.