geronimo-scm mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From akulshresh...@apache.org
Subject svn commit: r503417 - in /geronimo/server/trunk/modules/geronimo-management/src/main/java/org/apache/geronimo/management: geronimo/stats/ stats/
Date Sun, 04 Feb 2007 14:48:11 GMT
Author: akulshreshtha
Date: Sun Feb  4 06:48:10 2007
New Revision: 503417

URL: http://svn.apache.org/viewvc?view=rev&rev=503417
Log:
GERONIMO-1293 Added tomcat specific Stats interfaces and their implementation

Added:
    geronimo/server/trunk/modules/geronimo-management/src/main/java/org/apache/geronimo/management/geronimo/stats/WebConnectorStats.java
  (with props)
    geronimo/server/trunk/modules/geronimo-management/src/main/java/org/apache/geronimo/management/geronimo/stats/WebModuleStats.java
  (with props)
    geronimo/server/trunk/modules/geronimo-management/src/main/java/org/apache/geronimo/management/stats/WebConnectorStatsImpl.java
  (with props)
    geronimo/server/trunk/modules/geronimo-management/src/main/java/org/apache/geronimo/management/stats/WebModuleStatsImpl.java
  (with props)

Added: geronimo/server/trunk/modules/geronimo-management/src/main/java/org/apache/geronimo/management/geronimo/stats/WebConnectorStats.java
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/modules/geronimo-management/src/main/java/org/apache/geronimo/management/geronimo/stats/WebConnectorStats.java?view=auto&rev=503417
==============================================================================
--- geronimo/server/trunk/modules/geronimo-management/src/main/java/org/apache/geronimo/management/geronimo/stats/WebConnectorStats.java
(added)
+++ geronimo/server/trunk/modules/geronimo-management/src/main/java/org/apache/geronimo/management/geronimo/stats/WebConnectorStats.java
Sun Feb  4 06:48:10 2007
@@ -0,0 +1,80 @@
+/**
+ *
+ * Copyright 2006 The Apache Software Foundation
+ *
+ *  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.apache.geronimo.management.geronimo.stats;
+
+import javax.management.j2ee.statistics.Stats;
+import javax.management.j2ee.statistics.RangeStatistic;
+import javax.management.j2ee.statistics.TimeStatistic;
+import javax.management.j2ee.statistics.CountStatistic;
+
+/**
+ * Statistics exposed by a Tomcat web connector (http, https)
+ * 
+ * @version $Rev$ $Date$
+ */
+public interface WebConnectorStats extends Stats {
+
+    /**
+     * Gets the Time statistics (count, total, Max, Min) for requests (includes
+     * figures across all requests since statistics gathering started)
+     */
+    TimeStatistic getRequestTime();
+
+    /**
+     * Gets the number of errors that have been returned since statistics
+     * gathering started.
+     */
+    CountStatistic getErrorCount();
+
+    /**
+     * Gets the number of requests being processed concurrently (as well as the
+     * min and max since statistics gathering started).
+     */
+    RangeStatistic getActiveRequestCount();
+    
+    /**
+     * Gets the number of connections currently open (as well as the min and max
+     * since statistics gathering started).
+     */
+    RangeStatistic getOpenConnectionCount();
+    
+    /**
+     * Gets the number of threads currently available (as well as min and max 
+     * since statistics gathering started.
+     * current - The number of threads currently in the pool (currentThreadCount)
+     *         - the number of threads currently serving requests (currentThreadBusy)
+     *  HiMark    - The maximum number of unused threads that will be allowed to exist 
+     *              until the thread pool starts stopping the unnecessary threads(maxSpareThread)
+     * UpperBound - The max number of threads created by the connector (maxThreads)
+     * LowerBound - The number of threads created by the connector in the begining (minSpareThread)
+     */        
+    // This could be a container statistics
+    RangeStatistic getSpareThreadCount();
+    
+    /**
+     * Gets the number of requests handled by a particular connection (as well
+     * as the min(?) and max since statistics gathering started).
+     */
+    // RangeStatistic getConnectionRequestCount();
+
+    /**
+     * Gets the legnth of time that connections have been open (includes figures
+     * across all connections open at present)
+     */
+    // TimeStatistic getConnectionDuration();
+}

Propchange: geronimo/server/trunk/modules/geronimo-management/src/main/java/org/apache/geronimo/management/geronimo/stats/WebConnectorStats.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/server/trunk/modules/geronimo-management/src/main/java/org/apache/geronimo/management/geronimo/stats/WebConnectorStats.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/server/trunk/modules/geronimo-management/src/main/java/org/apache/geronimo/management/geronimo/stats/WebConnectorStats.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: geronimo/server/trunk/modules/geronimo-management/src/main/java/org/apache/geronimo/management/geronimo/stats/WebModuleStats.java
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/modules/geronimo-management/src/main/java/org/apache/geronimo/management/geronimo/stats/WebModuleStats.java?view=auto&rev=503417
==============================================================================
--- geronimo/server/trunk/modules/geronimo-management/src/main/java/org/apache/geronimo/management/geronimo/stats/WebModuleStats.java
(added)
+++ geronimo/server/trunk/modules/geronimo-management/src/main/java/org/apache/geronimo/management/geronimo/stats/WebModuleStats.java
Sun Feb  4 06:48:10 2007
@@ -0,0 +1,99 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You 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.apache.geronimo.management.geronimo.stats;
+
+import javax.management.j2ee.statistics.CountStatistic;
+import javax.management.j2ee.statistics.Stats;
+import javax.management.j2ee.statistics.TimeStatistic;
+
+/**
+ * @version $Rev$ $Date$
+ * 
+ */
+public interface WebModuleStats extends Stats {
+    // -----------------------
+    // static data
+    // -----------------------
+
+    /**
+     * @return The cumulative processing times of requests by all servlets in
+     *         this Context
+     */
+    public CountStatistic getProcessingTime();
+
+    /**
+     * @return The time this context was started.
+     */
+    // public CountStatistic getStartTime();
+    
+    /**
+     * @return The time (in milliseconds) it took to start this context.
+     */
+    public CountStatistic getStartupTime();
+
+    /**
+     * Scan the TLD contents of all tag library descriptor files (including
+     * those inside the jars that are 'accesible' to this webapp) and register
+     * any application event listeners found there.
+     * 
+     * @return
+     */
+    public CountStatistic getTldScanTime();
+
+    // -----------------------
+    // Transient data
+    // -----------------------
+
+    /**
+     * Gets the time (in seconds) that an expired session had been alive.
+     * (count, max, total)
+     * 
+     * @return Time (count, max, total) that an expired session had been alive.
+     */
+    public TimeStatistic getSessionAliveTime();
+
+    /**
+     * Returns the total number of sessions created by this manager
+     * 
+     * @return Total number of sessions created by this manager
+     */
+    public CountStatistic getSessionCount();
+
+    /**
+     * Gets the number of currently active sessions.
+     * 
+     * @return Number of currently active sessions
+     */
+    public CountStatistic getActiveSessionCount();
+
+    /**
+     * Gets the number of sessions that have expired.
+     * 
+     * @return Number of sessions that have expired
+     */
+    public CountStatistic getExpiredSessionCount();
+
+    /**
+     * Gets the number of sessions that were not created because the maximum
+     * number of active sessions was reached.
+     * 
+     * @return Number of rejected sessions
+     */
+    public CountStatistic getRejectedSessionCount();
+
+}

Propchange: geronimo/server/trunk/modules/geronimo-management/src/main/java/org/apache/geronimo/management/geronimo/stats/WebModuleStats.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/server/trunk/modules/geronimo-management/src/main/java/org/apache/geronimo/management/geronimo/stats/WebModuleStats.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/server/trunk/modules/geronimo-management/src/main/java/org/apache/geronimo/management/geronimo/stats/WebModuleStats.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: geronimo/server/trunk/modules/geronimo-management/src/main/java/org/apache/geronimo/management/stats/WebConnectorStatsImpl.java
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/modules/geronimo-management/src/main/java/org/apache/geronimo/management/stats/WebConnectorStatsImpl.java?view=auto&rev=503417
==============================================================================
--- geronimo/server/trunk/modules/geronimo-management/src/main/java/org/apache/geronimo/management/stats/WebConnectorStatsImpl.java
(added)
+++ geronimo/server/trunk/modules/geronimo-management/src/main/java/org/apache/geronimo/management/stats/WebConnectorStatsImpl.java
Sun Feb  4 06:48:10 2007
@@ -0,0 +1,170 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You 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.apache.geronimo.management.stats;
+
+import javax.management.j2ee.statistics.BoundedRangeStatistic;
+import javax.management.j2ee.statistics.CountStatistic;
+import javax.management.j2ee.statistics.RangeStatistic;
+import javax.management.j2ee.statistics.TimeStatistic;
+
+import org.apache.geronimo.management.geronimo.stats.WebConnectorStats;
+
+/**
+ * Geronimo implementation of the JSR-77 style WebConnectorStats interface. This
+ * is not required by JSR-77, but provides useful statistics. This will be
+ * discovered by mejb using 'stats' attribute.
+ * 
+ * @version $Revision$ $Date$
+ */
+
+public class WebConnectorStatsImpl extends StatsImpl implements WebConnectorStats {
+    private TimeStatisticImpl requestTime; // total, max, count
+
+    private CountStatisticImpl activeRequestCount;
+
+    private CountStatisticImpl errorCount;
+
+    private CountStatisticImpl bytesSentCount;
+
+    private CountStatisticImpl bytesReceivedCount;
+    
+    // these come from ThreadPool
+    private RangeStatisticImpl openConnectionCount; 
+    
+    private CountStatistic busyThreadCount;
+    
+    // TODO - change the name to BoundedRangeStatisticsImpl
+    private BoundedRangeImpl busyThreads;
+    // TODO - spareThreads metrics = current - busy, maxSpareThreads, minSpareThreads 
+
+    public WebConnectorStatsImpl() {
+        requestTime = new TimeStatisticImpl("Request Time", StatisticImpl.UNIT_TIME_MILLISECOND,
+                "The time to process all requests");
+        activeRequestCount = new CountStatisticImpl("Active Request Count", StatisticImpl.UNIT_COUNT,
+                "currently active requests ", 0);
+        errorCount = new CountStatisticImpl("Error Count", StatisticImpl.UNIT_COUNT,
+                "The numbet of Errors during the observed period", 0);
+        bytesSentCount = new CountStatisticImpl("Bytes Sent", StatisticImpl.UNIT_COUNT,
+                "The number of bytes sent during the observerd period", 0);
+        bytesReceivedCount = new CountStatisticImpl("Bytes Received", StatisticImpl.UNIT_COUNT,
+                "The number of bytes received during the observerd period", 0);
+        openConnectionCount = new RangeStatisticImpl("" + "Open Connections", StatisticImpl.UNIT_COUNT,
+                "Range for connections opened during the observed period", 0); // all 0's
+        busyThreads = new BoundedRangeImpl("Busy Threads", StatisticImpl.UNIT_COUNT,
+                "BoundedRange for Threads currently busy serving requests", 0, 0, 0);
+        addStat("RequestTime", requestTime); // better name
+        addStat("activeRequestCount", activeRequestCount);
+        addStat("errorCount", errorCount);
+        addStat("bytesSent", bytesSentCount);
+        addStat("bytesReceived", bytesReceivedCount);
+        addStat("openConnectionCount", openConnectionCount);
+        addStat("busyThreads", busyThreads);
+    }
+
+    public RangeStatistic getActiveRequestCount() {
+        // TODO 
+        return null;
+    }
+
+    public TimeStatistic getRequestTime() {
+        return requestTime;
+    }
+
+    public CountStatistic getErrorCount() {
+        return errorCount;
+    }
+
+    public CountStatistic getBytesSentCount() {
+        return bytesSentCount;
+    }
+
+    public CountStatistic getBytesReceivedCount() {
+        return bytesReceivedCount;
+    }
+   
+    public RangeStatistic getOpenConnectionCount() {
+        return openConnectionCount;
+    }
+    
+    // TODO - Move this to container statistics
+    public RangeStatistic getSpareThreadCount() {
+        return null;
+    }
+    
+    /**
+     * These setters are used by native implementation
+     */
+    public void setBytesReceivedCount(long bytesReceived) {
+        this.bytesReceivedCount.setCount(bytesReceived);
+    }
+
+    public void setBytesSentCount(long bytesSent) {
+        this.bytesSentCount.setCount(bytesSent);
+    }
+
+    public void setActiveRequestCount(int activeRequestCount) {
+        this.activeRequestCount.setCount(activeRequestCount);
+    }
+
+    public void setErrorCount(int errorCount) {
+        this.errorCount.setCount(errorCount);
+    }
+
+    public void setRequestTime(int count, long minTime, long maxTime, long totalTime) {
+        this.requestTime.setCount(count);
+        this.requestTime.setMinTime(minTime);
+        this.requestTime.setMaxTime(maxTime);
+        this.requestTime.setTotalTime(totalTime);
+    }
+ 
+    public void setOpenConnection(long current, long highMark, long lowMark) {
+        openConnectionCount.setCurrent(current);
+        openConnectionCount.setHighWaterMark(highMark);
+        openConnectionCount.setLowWaterMark(lowMark);
+    }
+    
+    public void setBusyThreads(long current, long highWaterMark, long lowWaterMark,
+            long upperBound, long lowerBound) {
+        busyThreads.setCurrent(current);
+        busyThreads.setHighWaterMark(highWaterMark);
+        busyThreads.setLowWaterMark(lowWaterMark); //0?
+        busyThreads.setLowerBound(lowerBound); //0?
+        busyThreads.setUpperBound(upperBound);  // always maxThreads
+    }
+    
+    /**
+     * Used to access the native implementation in order to call setters
+     * TODO implement these if needed by console
+     */
+    public RangeStatisticImpl getActiveRequestCountImpl() {
+        return null;
+    }
+
+    public TimeStatisticImpl getRequestDurationImpl() {
+        return null;
+    }
+
+    public CountStatisticImpl getTotalErrorCountImpl() {
+        return null;
+    }
+
+    public CountStatistic getTotalRequestCountImpl() {
+        return null;
+    }
+
+}

Propchange: geronimo/server/trunk/modules/geronimo-management/src/main/java/org/apache/geronimo/management/stats/WebConnectorStatsImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/server/trunk/modules/geronimo-management/src/main/java/org/apache/geronimo/management/stats/WebConnectorStatsImpl.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/server/trunk/modules/geronimo-management/src/main/java/org/apache/geronimo/management/stats/WebConnectorStatsImpl.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: geronimo/server/trunk/modules/geronimo-management/src/main/java/org/apache/geronimo/management/stats/WebModuleStatsImpl.java
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/modules/geronimo-management/src/main/java/org/apache/geronimo/management/stats/WebModuleStatsImpl.java?view=auto&rev=503417
==============================================================================
--- geronimo/server/trunk/modules/geronimo-management/src/main/java/org/apache/geronimo/management/stats/WebModuleStatsImpl.java
(added)
+++ geronimo/server/trunk/modules/geronimo-management/src/main/java/org/apache/geronimo/management/stats/WebModuleStatsImpl.java
Sun Feb  4 06:48:10 2007
@@ -0,0 +1,158 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You 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.apache.geronimo.management.stats;
+
+import javax.management.j2ee.statistics.CountStatistic;
+import javax.management.j2ee.statistics.TimeStatistic;
+
+import org.apache.geronimo.management.geronimo.stats.WebModuleStats;
+
+/**
+ * Geronimo implementation of the JSR-77 style WebModule interface. This
+ * is not required by JSR-77, but provides useful statistics for a web app
+ * 
+ * @version $Revison$ $Date$
+ */
+public class WebModuleStatsImpl extends StatsImpl implements WebModuleStats {
+    // Static data
+
+    private CountStatisticImpl processingTime;
+
+    private CountStatisticImpl startupTime;
+
+    private CountStatisticImpl tldScanTime;
+
+    // transient data
+    private TimeStatisticImpl sessionAliveTime; // total, max, count
+
+    private CountStatisticImpl sessionCount;
+
+    private CountStatisticImpl activeSessionCount;
+
+    private CountStatisticImpl rejectedSessionCount;
+
+    private CountStatisticImpl expiredSessionCount;
+
+    public WebModuleStatsImpl() {
+        processingTime = new CountStatisticImpl("Processing Time", StatisticImpl.UNIT_TIME_MILLISECOND,
+                "Time to process all the requests ", 0);
+        startupTime = new CountStatisticImpl("Startup Time", StatisticImpl.UNIT_TIME_MILLISECOND,
+                "Time to start this application", 0);
+        tldScanTime = new CountStatisticImpl("TLD Scan Time", StatisticImpl.UNIT_TIME_MILLISECOND,
+                "Time to scan TLDs ", 0);
+        sessionAliveTime = new TimeStatisticImpl("Session Alive Time", StatisticImpl.UNIT_TIME_SECOND,
+                "The time for session");
+        sessionCount = new CountStatisticImpl("Session Count", StatisticImpl.UNIT_COUNT,
+                "total number of sessions created ", 0);
+        activeSessionCount = new CountStatisticImpl("Active Session Count", StatisticImpl.UNIT_COUNT,
+                "currently active sessions ", 0);
+        rejectedSessionCount = new CountStatisticImpl("Rejected Session Count", StatisticImpl.UNIT_COUNT,
+                "rejected sessions ", 0);
+        expiredSessionCount = new CountStatisticImpl("Expired Session Count", StatisticImpl.UNIT_COUNT,
+                "expired sessions ", 0);
+        addStat("processingTime", processingTime);
+        addStat("startupTime", startupTime);
+        addStat("tldScanTime", tldScanTime);
+        addStat("sessionAliveTime", sessionAliveTime); // better name
+        addStat("sessionCount", sessionCount);
+        addStat("activeSessionCount", activeSessionCount);
+        addStat("rejectedSessionCount", rejectedSessionCount);
+        addStat("expiredSessionCount", expiredSessionCount);
+    }
+
+    public CountStatistic getProcessingTime() {
+        return processingTime;
+    }
+
+    public CountStatistic getStartupTime() {
+        return startupTime;
+    }
+
+    public CountStatistic getTldScanTime() {
+        return tldScanTime;
+    }
+
+    public TimeStatistic getSessionAliveTime() {
+        return sessionAliveTime;
+    }
+
+    public CountStatistic getSessionCount() {
+        return sessionCount;
+    }
+
+    public CountStatistic getActiveSessionCount() {
+        return activeSessionCount;
+    }
+
+    public CountStatistic getExpiredSessionCount() {
+        return expiredSessionCount;
+    }
+
+    public CountStatistic getRejectedSessionCount() {
+        return rejectedSessionCount;
+    }
+
+    /**
+     * These setters are used by native implementation
+     */
+
+    public void setProcessingTime(long processingTime) {
+        this.processingTime.setCount(processingTime);
+    }
+
+    // This is static data, need not be refreshed
+    public void setStartupTime(long startupTime) {
+        this.startupTime.setCount(startupTime);
+    }
+
+    public void setTldScanTime(long tldScanTime) {
+        this.tldScanTime.setCount(tldScanTime);
+    }
+
+    public void setSessionAliveTime(int count, long minTime, long maxTime, long totalTime)
{
+        this.sessionAliveTime.setCount(count);
+        this.sessionAliveTime.setMinTime(minTime);
+        this.sessionAliveTime.setMaxTime(maxTime);
+        this.sessionAliveTime.setTotalTime(totalTime);
+    }
+
+    public void setSessionCount(int sessionCount) {
+        this.sessionCount.setCount(sessionCount);
+    }
+
+    public void setActiveSessionCount(int activeSessionCount) {
+        this.activeSessionCount.setCount(activeSessionCount);
+    }
+
+    public void setExpiredSessionCount(int expiredSessionCount) {
+        this.expiredSessionCount.setCount(expiredSessionCount);
+    }
+
+    public void setRejectedSessionCount(int rejectedSessionCount) {
+        this.rejectedSessionCount.setCount(rejectedSessionCount);
+    }
+    
+    // Is this needed ?
+    public void setLastSampleTime(long time) {
+        sessionAliveTime.setLastSampleTime(time);
+        activeSessionCount.setLastSampleTime(time);
+        expiredSessionCount.setLastSampleTime(time);
+        rejectedSessionCount.setLastSampleTime(time);
+    }
+
+}

Propchange: geronimo/server/trunk/modules/geronimo-management/src/main/java/org/apache/geronimo/management/stats/WebModuleStatsImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/server/trunk/modules/geronimo-management/src/main/java/org/apache/geronimo/management/stats/WebModuleStatsImpl.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/server/trunk/modules/geronimo-management/src/main/java/org/apache/geronimo/management/stats/WebModuleStatsImpl.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain



Mime
View raw message