| /* |
| * Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved. |
| * |
| * This program and the accompanying materials are made available under the |
| * terms of the Eclipse Public License v. 2.0 which is available at |
| * http://www.eclipse.org/legal/epl-2.0, |
| * or the Eclipse Distribution License v. 1.0 which is available at |
| * http://www.eclipse.org/org/documents/edl-v10.php. |
| * |
| * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause |
| */ |
| |
| // Contributors: |
| // tware - contribution direct from Oracle TopLink |
| // tware - updates for new SessionProfiling API |
| package org.eclipse.persistence.tools.profiler.oracle; |
| |
| import java.io.Serializable; |
| import java.util.HashMap; |
| import java.util.Hashtable; |
| import java.util.Iterator; |
| import java.util.Map; |
| |
| import org.eclipse.persistence.internal.localization.DMSLocalization; |
| import org.eclipse.persistence.internal.sessions.AbstractRecord; |
| import org.eclipse.persistence.internal.sessions.AbstractSession; |
| import org.eclipse.persistence.logging.SessionLog; |
| import org.eclipse.persistence.queries.DatabaseQuery; |
| import org.eclipse.persistence.sessions.DataRecord; |
| import org.eclipse.persistence.sessions.Session; |
| import org.eclipse.persistence.sessions.SessionProfiler; |
| import org.eclipse.persistence.sessions.server.ServerSession; |
| |
| import oracle.dms.instrument.DMSConsole; |
| import oracle.dms.instrument.Event; |
| import oracle.dms.instrument.Noun; |
| import oracle.dms.instrument.PhaseEvent; |
| import oracle.dms.instrument.Sensor; |
| import oracle.dms.instrument.State; |
| import oracle.dms.spy.ConfigurationError; |
| import oracle.dms.spy.PublisherError; |
| import oracle.dms.spy.Spy; |
| |
| /** |
| * <b>Purpose</b>: Define the interface of EclipseLink profiler for using DMS gate.<p> |
| * <b>Description</b>: A mechanism used to provide a link for EclipseLink performance profiling by using the DMS tool. |
| * The predefined EclipseLink metrics will be monitored by using DMS sensors. EclipseLink library |
| * instrumentation will be done by inserting DMS calls for the purpose of measuring its performance<p> |
| * <b>Responsibilities</b>: |
| * <ul> |
| * <li> Define the EclipseLink metrics.</li> |
| * <li> Provide APIs to monitor the sensors at runtime.</li> |
| * <li> Change DMS sensor weight at runtime</li> |
| * </ul> |
| * @since TopLink 10.1.3 |
| */ |
| public class DMSPerformanceProfiler implements Serializable, Cloneable, SessionProfiler { |
| |
| //nouns type display name |
| public static final String EclipseLinkRootNoun = "/EclipseLink"; |
| public static final String SessionNounType = "EclipseLink Session"; |
| public static final String TransactionNounType = "EclipseLink Transaction"; |
| public static final String RcmNounType = "EclipseLink RCM"; |
| public static final String ConnectionNounType = "EclipseLink Connections"; |
| public static final String CacheNounType = "EclipseLink Cache"; |
| public static final String MiscellaneousNounType = "EclipseLink Miscellaneous"; |
| |
| public static final String ConnectionInUse = "ConnectionsInUse"; |
| public static final String MergeTime = "MergeTime"; |
| public static final String UnitOfWorkRegister = "UnitOfWorkRegister"; |
| public static final String DistributedMergeDmsDisplayName = "DistributedMerge"; |
| public static final String Sequencing = "Sequencing"; |
| |
| public static final String CONNECT = "connect"; |
| public static final String CACHE = "cache"; |
| |
| protected AbstractSession session; |
| protected Noun root; |
| protected Map<String, Sensor> normalWeightSensors; |
| protected Map<String, Sensor> heavyWeightSensors; |
| protected Map<String, Sensor> allWeightSensors; |
| protected Map<String, Sensor> normalAndHeavyWeightSensors; |
| protected Map<String, Sensor> normalHeavyAndAllWeightSensors; |
| protected Map<String, Noun> normalWeightNouns; |
| protected Map<String, Noun> heavyWeightNouns; |
| protected Map<String, Noun> allWeightNouns; |
| protected ThreadLocal<Map<String, Long>> operationStartTokenThreadLocal; |
| protected static boolean isDMSSpyInitialized; |
| protected int weight; |
| |
| /** |
| * PUBLIC: |
| * Create a new dms profiler. |
| * The profiler can be registered with a session to log performance information. |
| */ |
| public DMSPerformanceProfiler() { |
| this(null); |
| } |
| |
| /** |
| * PUBLIC: |
| * Create a new dms profiler. |
| * The profiler can be registered with a session to log performance information. |
| */ |
| public DMSPerformanceProfiler(Session session) { |
| this.session = (AbstractSession)session; |
| this.normalWeightNouns = new Hashtable<>(1); |
| this.heavyWeightNouns = new Hashtable<>(5); |
| this.allWeightNouns = new Hashtable<>(1); |
| this.normalWeightSensors = new Hashtable<>(4); |
| this.heavyWeightSensors = new Hashtable<>(); |
| this.allWeightSensors = new Hashtable<>(22); |
| this.normalAndHeavyWeightSensors = new Hashtable<>(); |
| this.normalHeavyAndAllWeightSensors = new Hashtable<>(); |
| this.operationStartTokenThreadLocal = new ThreadLocal<>(); |
| this.weight = DMSConsole.getSensorWeight(); |
| if (!isDMSSpyInitialized) { |
| isDMSSpyInitialized = true; |
| initSpy(); |
| } |
| } |
| |
| /** |
| * INTERNAL: |
| * Initialize TopLink noun tree based on dms weight. |
| */ |
| protected void initializeNounTree(int newWeight) { |
| if (newWeight == DMSConsole.NONE) { |
| destroyNounsByWeight(DMSConsole.NORMAL); |
| destroyNounsByWeight(DMSConsole.HEAVY); |
| destroyNounsByWeight(DMSConsole.ALL); |
| if (root != null) { |
| root.destroy(); |
| } |
| return; |
| } |
| |
| if (newWeight == DMSConsole.NORMAL) { |
| if (getProfileWeight() == DMSConsole.NONE) { |
| initializeNormalWeightSensors(); |
| } else if (getProfileWeight() == DMSConsole.HEAVY) { |
| destroyNounsByWeight(DMSConsole.HEAVY); |
| } else if (getProfileWeight() == DMSConsole.ALL) { |
| destroyNounsByWeight(DMSConsole.HEAVY); |
| destroyNounsByWeight(DMSConsole.ALL); |
| } |
| } |
| if (newWeight == DMSConsole.HEAVY) { |
| if (getProfileWeight() == DMSConsole.NONE) { |
| initializeNormalWeightSensors(); |
| initializeHeavyWeightSensors(); |
| } else if (getProfileWeight() == DMSConsole.NORMAL) { |
| initializeHeavyWeightSensors(); |
| } else if (getProfileWeight() == DMSConsole.ALL) { |
| destroyNounsByWeight(DMSConsole.ALL); |
| } |
| } |
| |
| if (newWeight == DMSConsole.ALL) { |
| if (getProfileWeight() == DMSConsole.NONE) { |
| initializeNormalWeightSensors(); |
| initializeHeavyWeightSensors(); |
| initializeAllWeightSensors(); |
| } else if (getProfileWeight() == DMSConsole.NORMAL) { |
| initializeHeavyWeightSensors(); |
| initializeAllWeightSensors(); |
| } else if (getProfileWeight() == DMSConsole.HEAVY) { |
| initializeAllWeightSensors(); |
| } |
| } |
| } |
| |
| /** |
| * INTERNAL: |
| * Api for changing dms weight dynamically. |
| */ |
| @Override |
| public void setProfileWeight(int newWeight) { |
| if (newWeight != this.weight) { |
| getSession().setIsInProfile(!(newWeight == DMSConsole.NONE)); |
| |
| // It is necessary to reset the weight to the real weight of NONE to trigger |
| //correct noun creation. This handles the case where the profiler |
| //instance is recreated and the weight is set to the DMSConsole weight |
| //which may differ since it currently does not change at runtime. |
| if (getNormalWeightNouns().isEmpty()) { |
| weight = DMSConsole.NONE; |
| } |
| initializeNounTree(newWeight); |
| weight = newWeight; |
| } |
| } |
| |
| /** |
| * INTERNAL: |
| * Initialize TopLink noun tree by default (DMSConsole.getSensorWeight()) |
| */ |
| @Override |
| public void initialize() { |
| weight = DMSConsole.NONE; |
| initializeNounTree(DMSConsole.getSensorWeight()); |
| weight = DMSConsole.getSensorWeight(); |
| |
| } |
| |
| /** |
| * INTERNAL: |
| * Return current TopLink dms weight. |
| */ |
| @Override |
| public int getProfileWeight() { |
| return weight; |
| } |
| |
| /** |
| * INTERNAL: |
| * Link to the dms PhaseEvent api start(). |
| */ |
| @Override |
| public void startOperationProfile(String operationName) { |
| //due to DMS bug3242994 can't set DMS weight to NONE |
| //shortcut for NORMAL weight since no operation profiles are every done for this level. |
| if (getProfileWeight() == DMSConsole.NORMAL) { |
| return; |
| } |
| Sensor phaseEvent = getSensorByName(operationName); |
| if (phaseEvent != null) { |
| Long startToken = ((PhaseEvent) phaseEvent).start(); |
| getPhaseEventStartToken().put(operationName, startToken); |
| } |
| } |
| |
| /** |
| * INTERNAL: |
| * Link to the dms PhaseEvent api start(). Intended to be used for query profiling. |
| */ |
| @Override |
| public void startOperationProfile(String operationName, DatabaseQuery query, int weight) { |
| //due to DMS bug3242994 can't set DMS weight to NONE |
| //shortcut for NORMAL weight since no operation profiles are every done for this level. |
| if (getProfileWeight() == DMSConsole.NORMAL) { |
| return; |
| } |
| if (getProfileWeight() < weight) { |
| return; |
| } |
| |
| Sensor phaseEvent = getPhaseEventForQuery(operationName, query, weight); |
| if (phaseEvent != null) { |
| Long startToken = ((PhaseEvent) phaseEvent).start(); |
| if (query != null) { |
| getPhaseEventStartToken().put(query.getSensorName(operationName, getSessionName()), startToken); |
| } else { |
| getPhaseEventStartToken().put(operationName, startToken); |
| } |
| } |
| } |
| |
| /** |
| * INTERNAL: |
| * Link to the dms PhaseEvent api stop(). |
| */ |
| @Override |
| public void endOperationProfile(String operationName) { |
| //due to DMS bug3242994 can't set DMS weight to NONE |
| //shortcut for NORMAL weight since no operation profiles are every done for this level. |
| if (getProfileWeight() == DMSConsole.NORMAL) { |
| return; |
| } |
| Sensor phaseEvent = getSensorByName(operationName); |
| if (phaseEvent != null) { |
| Long startTime = getPhaseEventStartToken().get(operationName); |
| ((PhaseEvent)phaseEvent).stop(startTime); |
| } |
| } |
| |
| /** |
| * INTERNAL: |
| * Link to the dms PhaseEvent api stop(). Intended to be used for query profiling. |
| */ |
| @Override |
| public void endOperationProfile(String operationName, DatabaseQuery query, int weight) { |
| //due to DMS bug3242994 can't set DMS weight to NONE |
| //shortcut for NORMAL weight since no operation profiles are every done for this level. |
| if (getProfileWeight() == DMSConsole.NORMAL) { |
| return; |
| } |
| if (getProfileWeight() < weight) { |
| return; |
| } |
| |
| Sensor phaseEvent = getPhaseEventForQuery(operationName, query, weight); |
| if (phaseEvent != null) { |
| Long startTime; |
| if (query != null) { |
| startTime = getPhaseEventStartToken().get(query.getSensorName(operationName, getSessionName())); |
| } else { |
| startTime = getPhaseEventStartToken().get(operationName); |
| } |
| ((PhaseEvent)phaseEvent).stop(startTime); |
| } |
| } |
| |
| /** |
| * INTERNAL: |
| * Link to the dms State api update(). |
| */ |
| @Override |
| public void update(String operationName, Object value) { |
| Sensor state = getSensorByName(operationName); |
| if (state != null) { |
| ((State)state).update(value); |
| } |
| } |
| |
| /** |
| * INTERNAL: |
| * Link to the dms Event api occurred(). |
| */ |
| @Override |
| public void occurred(String operationName, AbstractSession session) { |
| Sensor event = getSensorByName(operationName); |
| if (event != null) { |
| ((Event)event).occurred(); |
| } |
| } |
| |
| /** |
| * INTERNAL: |
| * Increase DMS Event sensor occurrence.(DMS) |
| */ |
| @Override |
| public void occurred(String operationName, DatabaseQuery query, AbstractSession session) { |
| Sensor event = getSensorByName(operationName); |
| if (event != null) { |
| ((Event)event).occurred(); |
| occurred(query.getMonitorName(), session); |
| } |
| } |
| |
| /** |
| * INTERNAL: |
| * Look for sensor for the name: TopLink_<sessionName>_<domainClass>_<queryClass>_<queryName>(if exist)_<operationName>(if exist). |
| * If not found, look for the noun the sensor should be built on. If the noun is not found, create a new one. Create the sensor |
| * based on the noun. |
| */ |
| protected Sensor getPhaseEventForQuery(String operationName, DatabaseQuery query, int weight) { |
| String sensorName; |
| if (query != null) { |
| sensorName = query.getSensorName(operationName, getSessionName()); |
| } else { |
| sensorName = operationName; |
| } |
| |
| Sensor phaseEvent = getSensorByName(sensorName); |
| |
| if (phaseEvent == null) { |
| Noun queryNoun; |
| if (query != null) { |
| String queryNounName = query.getQueryNounName(getSessionName()); |
| queryNoun = getNounByType(queryNounName, null, DMSConsole.HEAVY); |
| if (queryNoun == null) { |
| Noun domainClassNoun = getNounByType(query.getDomainClassNounName(getSessionName()), root, DMSConsole.HEAVY); |
| queryNoun = getNounByType(queryNounName, domainClassNoun, DMSConsole.HEAVY); |
| } |
| phaseEvent = PhaseEvent.create(queryNoun, sensorName, DMSLocalization.buildMessage("query", new Object[]{sensorName})); |
| } else { |
| queryNoun = getAllWeightNouns().get(MiscellaneousNounType); |
| phaseEvent = PhaseEvent.create(queryNoun, sensorName, DMSLocalization.buildMessage("query_misc", new Object[]{sensorName})); |
| } |
| phaseEvent.deriveMetric(Sensor.all); |
| if (weight == DMSConsole.HEAVY) { |
| getHeavyWeightSensors().put(sensorName, phaseEvent); |
| getNormalAndHeavyWeightSensors().put(sensorName, phaseEvent); |
| } else if (weight == DMSConsole.ALL) { |
| getAllWeightSensors().put(sensorName, phaseEvent); |
| getNormalHeavyAndAllWeightSensors().put(sensorName, phaseEvent); |
| } |
| } |
| |
| return phaseEvent; |
| } |
| |
| /** |
| * INTERNAL: |
| * Look for noun based on the given type and weight. If not found and the parent noun is not null, create a new noun. |
| */ |
| protected Noun getNounByType(String type, Noun parentNoun, int weight) { |
| if (getProfileWeight() < weight) { |
| return null; |
| } |
| Noun noun = null; |
| Map<String, Noun> map = null; |
| if (weight == DMSConsole.NORMAL) { |
| map = getNormalWeightNouns(); |
| } else if (weight == DMSConsole.HEAVY) { |
| map = getHeavyWeightNouns(); |
| } else if (weight == DMSConsole.ALL) { |
| map = getAllWeightNouns(); |
| } |
| if (map != null) { |
| noun = map.get(type); |
| if (noun == null) { |
| if (parentNoun != null) { |
| noun = Noun.create(parentNoun, type, type); |
| map.put(type, noun); |
| } |
| } |
| } |
| |
| return noun; |
| } |
| |
| /** |
| * INTERNAL: |
| * Return dms sensor which created by pre-defined TopLink metrics. |
| */ |
| protected Sensor getSensorByName(String operationName) { |
| Sensor sensor = null; |
| if (getProfileWeight() == DMSConsole.NORMAL) { |
| sensor = getNormalWeightSensors().get(operationName); |
| } else if (getProfileWeight() == DMSConsole.HEAVY) { |
| sensor = getNormalAndHeavyWeightSensors().get(operationName); |
| } else if (getProfileWeight() == DMSConsole.ALL) { |
| sensor = getNormalHeavyAndAllWeightSensors().get(operationName); |
| } |
| return sensor; |
| } |
| |
| /** |
| * INTERNAL: |
| * Create root noun for TopLink dms metrics. |
| */ |
| protected void createRootNoun() { |
| root = Noun.create(EclipseLinkRootNoun); |
| } |
| |
| /** |
| * INTERNAL: |
| * Build dms NORMAL weight sensors for TopLink dms metrics. |
| */ |
| protected void initializeNormalWeightSensors() { |
| createRootNoun(); |
| Noun sessionNoun = Noun.create(root, "Session" + getSessionName(), SessionNounType); |
| |
| //SessionName |
| State.create(sessionNoun, SessionProfiler.SessionName, "", DMSLocalization.buildMessage("session_name"), (this.getSession().getName() == "") ? "session name not specified" : getSession().getName()); |
| |
| //LoginTime |
| State sessionLoginTime = State.create(sessionNoun, SessionProfiler.LoginTime, "", DMSLocalization.buildMessage("session_login_time"), "not available"); |
| this.getNormalWeightSensors().put(SessionProfiler.LoginTime, sessionLoginTime); |
| this.getNormalWeightNouns().put(SessionNounType, sessionNoun); |
| } |
| |
| /** |
| * INTERNAL: |
| * Build dms HEAVY weight sensors for TopLink dms metrics. |
| */ |
| protected void initializeHeavyWeightSensors() { |
| Noun baseSessionNoun = getNormalWeightNouns().get(SessionNounType); |
| |
| //clientSession |
| Event clientSession = Event.create(baseSessionNoun, SessionProfiler.ClientSessionCreated, DMSLocalization.buildMessage("client_session_count")); |
| getHeavyWeightSensors().put(SessionProfiler.ClientSessionCreated, clientSession); |
| //UnitOfWork |
| Event unitOfWork = Event.create(baseSessionNoun, SessionProfiler.UowCreated, DMSLocalization.buildMessage("unitofwork_count")); |
| getHeavyWeightSensors().put(SessionProfiler.UowCreated, unitOfWork); |
| |
| Noun transactionNoun = Noun.create(root, "Transaction" + getSessionName(), TransactionNounType); |
| getHeavyWeightNouns().put(TransactionNounType, transactionNoun); |
| |
| //UowOfWorkCommits |
| PhaseEvent uowCommit = PhaseEvent.create(transactionNoun, SessionProfiler.UowCommit, DMSLocalization.buildMessage("unitofwork_commit")); |
| uowCommit.deriveMetric(Sensor.all); |
| getHeavyWeightSensors().put(SessionProfiler.UowCommit, uowCommit); |
| Event uowCommits = Event.create(transactionNoun, SessionProfiler.UowCommits, DMSLocalization.buildMessage("unitofwork_commits")); |
| getHeavyWeightSensors().put(SessionProfiler.UowCommits, uowCommits); |
| //UnitOfWorkRollbacks |
| Event uowRollbacks = Event.create(transactionNoun, SessionProfiler.UowRollbacks, DMSLocalization.buildMessage("unitofwork_rollback")); |
| getHeavyWeightSensors().put(SessionProfiler.UowRollbacks, uowRollbacks); |
| //OptimisticLocks |
| Event optimisticLock = Event.create(transactionNoun, SessionProfiler.OptimisticLockException, DMSLocalization.buildMessage("optimistic_lock")); |
| getHeavyWeightSensors().put(SessionProfiler.OptimisticLockException, optimisticLock); |
| |
| //RCM noun |
| Noun rcmNoun = Noun.create(root, "RCM" + getSessionName(), RcmNounType); |
| getHeavyWeightNouns().put(RcmNounType, rcmNoun); |
| |
| //Status |
| State rcmStatus = State.create(rcmNoun, SessionProfiler.RcmStatus, "", DMSLocalization.buildMessage("rcm_status"), "not available"); |
| getHeavyWeightSensors().put(SessionProfiler.RcmStatus, rcmStatus); |
| //MessagesReceived |
| Event messagesReceived = Event.create(rcmNoun, SessionProfiler.RcmReceived, DMSLocalization.buildMessage("rcm_message_received")); |
| getHeavyWeightSensors().put(SessionProfiler.RcmReceived, messagesReceived); |
| //MessagesSent |
| Event messagesSent = Event.create(rcmNoun, SessionProfiler.RcmSent, DMSLocalization.buildMessage("rcm_message_sent")); |
| getHeavyWeightSensors().put(SessionProfiler.RcmSent, messagesSent); |
| //RemoteChangeSets |
| Event remoteChangeSets = Event.create(rcmNoun, SessionProfiler.RemoteChangeSet, DMSLocalization.buildMessage("remote_change_set")); |
| getHeavyWeightSensors().put(SessionProfiler.RemoteChangeSet, remoteChangeSets); |
| |
| //connections noun |
| Noun connectionsNoun = Noun.create(root, "Connection" + getSessionName(), ConnectionNounType); |
| getHeavyWeightNouns().put(ConnectionNounType, connectionsNoun); |
| //ConnectionsInUse |
| if (getSession().isServerSession()) { |
| Iterator<String> enumtr = ((ServerSession)getSession()).getConnectionPools().keySet().iterator(); |
| while (enumtr.hasNext()) { |
| String poolName = enumtr.next(); |
| State connectionInUse = State.create(connectionsNoun, ConnectionInUse + "(" + poolName + ")", "", DMSLocalization.buildMessage("connection_in_used"), "not available"); |
| getHeavyWeightSensors().put(poolName, connectionInUse); |
| } |
| } |
| |
| //ConnectionHealth Ping |
| PhaseEvent connectionPing = PhaseEvent.create(connectionsNoun, SessionProfiler.ConnectionPing, DMSLocalization.buildMessage("connection_ping")); |
| connectionPing.deriveMetric(Sensor.all); |
| this.getAllWeightSensors().put(SessionProfiler.ConnectionPing, connectionPing); |
| |
| //ConnectCalls |
| Event tl_connects = Event.create(connectionsNoun, SessionProfiler.Connects, DMSLocalization.buildMessage("connect_call")); |
| getHeavyWeightSensors().put(SessionProfiler.Connects, tl_connects); |
| //DisconnectCalls |
| Event tl_disconnects = Event.create(connectionsNoun, SessionProfiler.Disconnects, DMSLocalization.buildMessage("disconnect_call")); |
| getHeavyWeightSensors().put(SessionProfiler.Disconnects, tl_disconnects); |
| |
| //cache noun |
| Noun cacheNoun = Noun.create(root, "Cache" + getSessionName(), CacheNounType); |
| getHeavyWeightNouns().put(CacheNounType, cacheNoun); |
| //CacheHits |
| Event cacheHits = Event.create(cacheNoun, SessionProfiler.CacheHits, DMSLocalization.buildMessage("cache_hits")); |
| getHeavyWeightSensors().put(SessionProfiler.CacheHits, cacheHits); |
| //CacheMisses |
| Event cacheMisses = Event.create(cacheNoun, SessionProfiler.CacheMisses, DMSLocalization.buildMessage("cache_misses")); |
| getHeavyWeightSensors().put(SessionProfiler.CacheMisses, cacheMisses); |
| |
| //put in NormalAndHeavyWeightSensors |
| getNormalAndHeavyWeightSensors().putAll(getNormalWeightSensors()); |
| getNormalAndHeavyWeightSensors().putAll(getHeavyWeightSensors()); |
| } |
| |
| /** |
| * INTERNAL: |
| * Build dms ALL weight sensors for TopLink dms metrics. |
| */ |
| protected void initializeAllWeightSensors() { |
| //MergeTime |
| Noun baseTransactionNoun = getHeavyWeightNouns().get(TransactionNounType); |
| PhaseEvent mergeTime = PhaseEvent.create(baseTransactionNoun, MergeTime, DMSLocalization.buildMessage("merge_time")); |
| mergeTime.deriveMetric(Sensor.all); |
| this.getAllWeightSensors().put(SessionProfiler.Merge, mergeTime); |
| |
| //JTS afterCompletion |
| PhaseEvent jtsAferCompletion = PhaseEvent.create(baseTransactionNoun, SessionProfiler.JtsAfterCompletion, DMSLocalization.buildMessage("jts_aftercompletion")); |
| jtsAferCompletion.deriveMetric(Sensor.all); |
| this.getAllWeightSensors().put(SessionProfiler.JtsAfterCompletion, jtsAferCompletion); |
| |
| //JTS beforeCompletion |
| PhaseEvent jtsBeforeCompletion = PhaseEvent.create(baseTransactionNoun, SessionProfiler.JtsBeforeCompletion, DMSLocalization.buildMessage("jts_beforecompletion")); |
| jtsBeforeCompletion.deriveMetric(Sensor.all); |
| this.getAllWeightSensors().put(SessionProfiler.JtsBeforeCompletion, jtsBeforeCompletion); |
| |
| //UnitOfWorkRegister |
| PhaseEvent uowRegister = PhaseEvent.create(baseTransactionNoun, UnitOfWorkRegister, DMSLocalization.buildMessage("unitofwork_register")); |
| uowRegister.deriveMetric(Sensor.all); |
| this.getAllWeightSensors().put(SessionProfiler.Register, uowRegister); |
| //DistributedMerge |
| PhaseEvent distributedMerge = PhaseEvent.create(baseTransactionNoun, DistributedMergeDmsDisplayName, DMSLocalization.buildMessage("distributed_merge")); |
| distributedMerge.deriveMetric(Sensor.all); |
| this.getAllWeightSensors().put(SessionProfiler.DistributedMerge, distributedMerge); |
| |
| //assigning sequence numbers |
| PhaseEvent sequence = PhaseEvent.create(baseTransactionNoun, Sequencing, DMSLocalization.buildMessage("assigning_sequence_numbers")); |
| sequence.deriveMetric(Sensor.all); |
| this.getAllWeightSensors().put(SessionProfiler.AssignSequence, sequence); |
| |
| //Caching |
| Noun baseCacheNoun = getHeavyWeightNouns().get(CacheNounType); |
| PhaseEvent cache = PhaseEvent.create(baseCacheNoun, SessionProfiler.Caching, DMSLocalization.buildMessage("caching")); |
| cache.deriveMetric(Sensor.all); |
| this.getAllWeightSensors().put(CACHE, cache); |
| |
| //Connection |
| Noun baseConnectionNoun = getHeavyWeightNouns().get(ConnectionNounType); |
| PhaseEvent dbConnect = PhaseEvent.create(baseConnectionNoun, SessionProfiler.ConnectionManagement, DMSLocalization.buildMessage("connection")); |
| dbConnect.deriveMetric(Sensor.all); |
| this.getAllWeightSensors().put(CONNECT, dbConnect); |
| |
| //rcm |
| Noun baseRcmNoun = getHeavyWeightNouns().get(RcmNounType); |
| |
| //ChangeSetsMerged |
| Event changeSetsProcessed = Event.create(baseRcmNoun, SessionProfiler.ChangeSetsProcessed, DMSLocalization.buildMessage("change_set_processed")); |
| getAllWeightSensors().put(SessionProfiler.ChangeSetsProcessed, changeSetsProcessed); |
| //ChangeSetsNotMerged |
| Event changeSetsNotProcessed = Event.create(baseRcmNoun, SessionProfiler.ChangeSetsNotProcessed, DMSLocalization.buildMessage("change_set_not_processed")); |
| getAllWeightSensors().put(SessionProfiler.ChangeSetsNotProcessed, changeSetsNotProcessed); |
| |
| //miscellaneous noun |
| Noun miscellaneousNoun = Noun.create(root, "Miscellaneous" + getSessionName(), MiscellaneousNounType); |
| getAllWeightNouns().put(MiscellaneousNounType, miscellaneousNoun); |
| |
| //Logging |
| PhaseEvent logging = PhaseEvent.create(miscellaneousNoun, SessionProfiler.Logging, DMSLocalization.buildMessage("logging")); |
| logging.deriveMetric(Sensor.all); |
| this.getAllWeightSensors().put(SessionProfiler.Logging, logging); |
| |
| //DescriptorEvents |
| PhaseEvent descriptorEvent = PhaseEvent.create(miscellaneousNoun, SessionProfiler.DescriptorEvent, DMSLocalization.buildMessage("descriptor_event")); |
| descriptorEvent.deriveMetric(Sensor.all); |
| this.getAllWeightSensors().put(SessionProfiler.DescriptorEvent, descriptorEvent); |
| |
| //SessionEvents |
| PhaseEvent sessionEvent = PhaseEvent.create(miscellaneousNoun, SessionProfiler.SessionEvent, DMSLocalization.buildMessage("session_event")); |
| sessionEvent.deriveMetric(Sensor.all); |
| this.getAllWeightSensors().put(SessionProfiler.SessionEvent, sessionEvent); |
| |
| //put in NormalHeavyAndAllWeightSensors |
| getNormalHeavyAndAllWeightSensors().putAll(getNormalAndHeavyWeightSensors()); |
| getNormalHeavyAndAllWeightSensors().putAll(getAllWeightSensors()); |
| } |
| |
| /** |
| * INTERNAL: |
| * This method is useful for standalone TopLink application |
| * Initialize DMS, should be called once and should be called before any other DMS calls. |
| */ |
| protected void initSpy() { |
| try { |
| Spy.init("TopLink", null); |
| } catch (PublisherError p) { |
| getSession().log(SessionLog.WARNING, SessionLog.DMS, "an_error_occured_initializing_dms_listener"); |
| getSession().logThrowable(SessionLog.WARNING, SessionLog.DMS, p); |
| setProfileWeight(DMSConsole.NONE); |
| } catch (ConfigurationError c) { |
| getSession().log(SessionLog.WARNING, SessionLog.DMS, "an_error_occured_initializing_dms_listener"); |
| getSession().logThrowable(SessionLog.WARNING, SessionLog.DMS, c); |
| setProfileWeight(DMSConsole.NONE); |
| } |
| } |
| |
| /** |
| * INTERNAL: |
| * Destroy sensors based on dms weight when user changes the weight at runtime. |
| */ |
| protected void destroySensorsByWeight(int weight) { |
| Iterator<Sensor> iterator = null; |
| if (weight == DMSConsole.HEAVY) { |
| iterator = getHeavyWeightSensors().values().iterator(); |
| } else if (weight == DMSConsole.ALL) { |
| iterator = getAllWeightSensors().values().iterator(); |
| } |
| if (iterator != null) { |
| while (iterator.hasNext()) { |
| iterator.next().destroy(); |
| } |
| } |
| } |
| |
| /** |
| * INTERNAL: |
| * Destroy nouns based on dms weight when user changes the weight at runtime. |
| */ |
| protected void destroyNounsByWeight(int weight) { |
| if (weight == DMSConsole.NORMAL) { |
| Iterator<Noun> iterator = getNormalWeightNouns().values().iterator(); |
| while (iterator.hasNext()) { |
| iterator.next().destroy(); |
| } |
| getNormalWeightNouns().clear(); |
| getNormalWeightSensors().clear(); |
| } |
| if (weight == DMSConsole.HEAVY) { |
| Iterator<Noun> iterator = getHeavyWeightNouns().values().iterator(); |
| while (iterator.hasNext()) { |
| iterator.next().destroy(); |
| } |
| getHeavyWeightNouns().clear(); |
| destroySensorsByWeight(DMSConsole.HEAVY); |
| getNormalAndHeavyWeightSensors().clear(); |
| getHeavyWeightSensors().clear(); |
| } |
| if (weight == DMSConsole.ALL) { |
| Iterator<Noun> iterator = getAllWeightNouns().values().iterator(); |
| while (iterator.hasNext()) { |
| iterator.next().destroy(); |
| } |
| getAllWeightNouns().clear(); |
| destroySensorsByWeight(DMSConsole.ALL); |
| getNormalHeavyAndAllWeightSensors().clear(); |
| getAllWeightSensors().clear(); |
| } |
| } |
| |
| protected Map<String, Long> getPhaseEventStartToken() { |
| if (getOperationStartTokenThreadLocal().get() == null) { |
| getOperationStartTokenThreadLocal().set(new HashMap<>()); |
| } |
| return getOperationStartTokenThreadLocal().get(); |
| } |
| |
| protected Map<String, Sensor> getNormalWeightSensors() { |
| return normalWeightSensors; |
| } |
| |
| protected Map<String, Sensor> getHeavyWeightSensors() { |
| return heavyWeightSensors; |
| } |
| |
| protected Map<String, Sensor> getAllWeightSensors() { |
| return allWeightSensors; |
| } |
| |
| protected Map<String, Sensor> getNormalAndHeavyWeightSensors() { |
| return normalAndHeavyWeightSensors; |
| } |
| |
| protected Map<String, Sensor> getNormalHeavyAndAllWeightSensors() { |
| return normalHeavyAndAllWeightSensors; |
| } |
| |
| protected Map<String, Noun> getNormalWeightNouns() { |
| return normalWeightNouns; |
| } |
| |
| protected Map<String, Noun> getHeavyWeightNouns() { |
| return heavyWeightNouns; |
| } |
| |
| protected Map<String, Noun> getAllWeightNouns() { |
| return allWeightNouns; |
| } |
| |
| protected ThreadLocal<Map<String, Long>> getOperationStartTokenThreadLocal() { |
| return operationStartTokenThreadLocal; |
| } |
| |
| public AbstractSession getSession() { |
| return session; |
| } |
| |
| public String getSessionName() { |
| if (getSession().getName() != "") { |
| return "_" + getSession().getName(); |
| } else { |
| return getSession().getName(); |
| } |
| } |
| |
| @Override |
| public void setSession(Session session) { |
| this.session = (AbstractSession)session; |
| } |
| |
| @Override |
| public Object profileExecutionOfQuery(DatabaseQuery query, DataRecord row, AbstractSession session) { |
| //This is to profile the query execution and no operation name is given |
| startOperationProfile(null, query, DMSConsole.HEAVY); |
| Object result = null; |
| try { |
| result = session.internalExecuteQuery(query, (AbstractRecord)row); |
| } finally { |
| endOperationProfile(null, query, DMSConsole.HEAVY); |
| } |
| return result; |
| } |
| } |