I want to measure the time from the start of an incoming HTTP request and the application getting to a certain point. Both those points in time are located in different classes. How would I start and stop a timer from these different classes. I don't see a way to use 'named' timers from the MeterRegistry.
How would I go about this?
You can use AOP as below :
#Aspect
#Component
public class ControllerMonitor {
protected static final Logger LOGGER = LoggerFactory.getLogger(ControllerMonitor.class);
#Before("execution(public * com.demo.controller.*Controller.*(..))")
public void logBeforeAccess(JoinPoint joinPoint) {
if(joinPoint!=null){
String packageName = joinPoint.getSignature()!=null?joinPoint.getSignature().getDeclaringTypeName():"LOG-404";
LOGGER.info(". . .A request initiated from controller [" + packageName + "."+ getMethodSignature(joinPoint) + "]. . .");
}
}
#After("execution(public * com.demo.controller.*Controller.*(..))")
public void logAfterAccess(JoinPoint joinPoint) {
if(joinPoint!=null){
String packageName = joinPoint.getSignature()!=null?joinPoint.getSignature().getDeclaringTypeName():"LOG-404";
LOGGER.info(". . .Request from controller [" + packageName + "."+ getMethodSignature(joinPoint) + "] completed. . .");
}
}
#AfterThrowing(pointcut = "execution(public * com.demo.controller.*Controller.*(..))",throwing="exception")
public void logAfterThrowing(Exception exception){
LOGGER.error("Exception caught:"+ exception.getMessage());
}
private String getMethodSignature(JoinPoint joinPoint){
if(joinPoint!=null){
String methodName = joinPoint.getSignature().getName();
Object[] arguments = joinPoint.getArgs();
StringBuilder sb=new StringBuilder();
if(arguments!=null){
for (Object param: arguments) {
sb.append(param).append(",");
}
sb =(sb.length()>1)?sb.deleteCharAt(sb.length()-1):sb;
}
methodName = methodName+"("+new String(sb)+")";
return methodName;
}else{
return "LOG-405";
}
}
}
Use AOP …...No need to do changes on each class level. It will be one place config..
Related
So im trying to implement basic listener for when some value is set on redis, but when i set some value nothing happens and only expiry event gets called.
Subscriber
public class Subscriber {
private static JedisPool pool;
public static void main(String[] args) {
JedisPool pool = new JedisPool("localhost");
Jedis jedis = pool.getResource();
jedis.psubscribe(new SubListener(), "*");
}
}
SubListener
public class SubListener extends JedisPubSub {
#Override
public void onPSubscribe(String pattern, int subscribedChannels) {
System.out.println("onPSubscribe "
+ pattern + " " + subscribedChannels);
}
#Override
public void onPMessage(String pattern, String channel, String message) {
System.out
.println("onPMessage pattern "
+ pattern + " " + channel + " " + message);
}
}
Edit: i found out that i had the notify-keyspace-events in config set to Ex. Now i set it to KEA to call on every event but what should i use to only call the event on set
To only call the event on set, set the config to Ks
How can I check whether my Java application is running as "SYSTEM"/"Local System" (as seen on Windows Service list)?
I tried using this:
System.out.println("Running with user: " + System.getenv().get("USERDOMAIN") + "\\" + System.getenv().get("USERNAME"));
... but it seems to return DOMAIN\COMPUTERNAME according where the program is run. So it can be like DOMAIN1\COMPUTER1 and somewhere else it is FOO\SERVER451 and both still means "SYSTEM" account.
For background information, my Java application is wrapped to a Windows Service with 'Apache Commons Daemon Service Runner' and by default it will run as "Local System" (same way as in example image).
I really would want to simplify my code to print either SYSTEM or MYDOMAIN\JackTheUser depending on user type... Is there a way to do it with Java?
EDIT 20/12/02:
This is what I have done meanwhile the SO army working to find the correct answer:
Main:
String username = System.getenv().get("USERNAME");
String userdomain = System.getenv().get("USERDOMAIN");
String servername = getComputerName();
if (username.equalsIgnoreCase((servername + "$"))) {
System.out.println("Running with user: 'Local System'("
+ userdomain + "\\" + username + ")");
} else {
System.out.println("Running with user: '" + userdomain + "\\"
+ username + "'");
}
Methods:
private static String getComputerName() {
Map<String, String> env = System.getenv();
if (env.containsKey("COMPUTERNAME"))
return env.get("COMPUTERNAME");
else if (env.containsKey("HOSTNAME"))
return env.get("HOSTNAME");
else
return "Unknown Host name";
}
Prints:
Running with user: 'MYDOMAIN\jokkeri' or Running with user: 'Local System'(MYSERVER\SERVER_1$)
(not a perfect solution and I'm sure there are many occasions where it won't work but it's a starting point)
EDIT2 20/12/02:
Some good information about SYSTEM account was found from this thread from superuser: https://superuser.com/questions/265216/windows-account-ending-with
That’s the best I can come up so far
private static final String APP_NAME = "Some App";
private static final Configuration CONFIG = new Configuration() {
public #Override AppConfigurationEntry[] getAppConfigurationEntry(String name) {
return name.equals(APP_NAME)?
new AppConfigurationEntry[] { new AppConfigurationEntry(
"com.sun.security.auth.module.NTLoginModule",
LoginModuleControlFlag.REQUIRED, Collections.emptyMap())}:
null;
}
};
static final boolean DEBUG = true;
public static void main(String[] args) throws LoginException {
LoginContext lc = new LoginContext(APP_NAME, null, null, CONFIG);
lc.login();
final Subject subject=lc.getSubject();
boolean isSystem = false;
try {
for(Principal p: subject.getPrincipals()) {
if(DEBUG) System.out.println(p);
if(p.toString().equals("NTSidUserPrincipal: S-1-5-18")) {
isSystem = true;
if(DEBUG) System.out.println("\tit's SYSTEM");
}
}
}
finally { lc.logout(); }
}
As explained in this answer, SYSTEM is a set of permissions that can be attached to different accounts. The code iterates over all principals associated with the current account and tests for the well known SYSTEM.
But if you’re only interested in a printable user name, you may check for the NTUserPrincipal.
LoginContext lc = new LoginContext(APP_NAME, null, null, CONFIG);
lc.login();
final Subject subject=lc.getSubject();
try {
String name = System.getProperty("user.name"); // just a fall-back
for(Principal p: subject.getPrincipals()) {
if(p.toString().startsWith("NTUserPrincipal: ")) {
name = p.getName();
break;
}
}
System.out.println("Hello " + name);
}
finally { lc.logout(); }
If you can live with a direct dependency to the com.sun.security.auth package (or jdk.security.auth module in Java 9+), you can use the specific principal types directly
LoginContext lc = new LoginContext(APP_NAME, null, null, CONFIG);
lc.login();
final Subject subject=lc.getSubject();
try {
boolean system = false;
for(NTSidUserPrincipal p: subject.getPrincipals(NTSidUserPrincipal.class)) {
if(p.getName().equals("S-1-5-18")) {
system = true;
break;
}
}
Set<NTUserPrincipal> up = subject.getPrincipals(NTUserPrincipal.class);
String name = up.isEmpty()?
System.getProperty("user.name"): up.iterator().next().getName();
System.out.println("Hello " + name+(system? " *": ""));
}
finally { lc.logout(); }
I'm trying to find all routes associated with a camel context?
I can't find the camel exchange getContext() data sheets so I know what methods can be called?
I have a dynamic route builder, drop a config file and the route gets created.
I need to create the routes in registry, as not started, and use a JGroups/Controlbus route that controls who is the active route. But I can't figure out how to get all routes associated with a camel context? if you can shed some light on this, I'd really be in your dept. thanks in advance.
This is what I have but I can't get to work, found on stacktrace.
#Override
public void process(Exchange exchange) throws Exception {
List<ProcessorDefinition<?>> outputProcessorDefs = exchange.getContext().getRouteDefinition("[routeId]").getOutputs();
for ( ProcessorDefinition rte : outputProcessorDefs ) {
log.info("ROUTES: " + rte);
}
}
thanks to a question answered by Claus How to find all Endpoints of route (Apache Camel, Java)
I was able to locate some info and found another simpler way to do this.
public void process(Exchange exchange) throws Exception {
List<Route> routeList = exchange.getContext().getRoutes();
for ( Route rte : routeList ) {
log.info("ROUTES: " + rte.getId());
}
This is my test for JGroups ControlBus management made possible by getRoutes() for dynamic route creation.
public class EndpointControlBusFileRouteBuilder extends RouteBuilder {
private static final Logger log = LoggerFactory.getLogger(EndpointControlBusFileRouteBuilder.class);
private String routeId;
private String ClusterId;
public EndpointControlBusFileRouteBuilder(String routeId) {
this.routeId = routeId;
}
#Override
public void configure() throws Exception {
log.info("*** JGroups routeCluster - RouteId : " + routeId + " ***");
ClusterId = routeId + ".JGroups";
from("jgroups:" + ClusterId + "?enableViewMessages=true&channelProperties=etc/jgroups.xml")
.autoStartup(true)
.routeId(ClusterId)
.filter(dropNonCoordinatorViews())
.threads().delay(delayIfContextNotStarted(SECONDS.toMillis(5))) // run in separated and delayed thread. Delay only if the context hasn't been started already.
.log("Starting JGroups JChannel Routes Consumer!!!!!!!!!!!!!!!!!!!!!")
.to("controlbus:route?routeId=" + routeId + "&action=start&async=true");
}
}
public class EndpointControlBusProcessor implements Processor {
private String routeId = "";
private static final Logger log = LoggerFactory.getLogger(EndpointControlBusProcessor.class);
#Override
public void process(Exchange exchange) throws Exception {
List<Route> routeList = exchange.getContext().getRoutes();
ProducerTemplate template = exchange.getContext().createProducerTemplate();
for ( Route rte : routeList ) {
routeId = rte.getId();
// log.info("ROUTES: " + routeId);
// ServiceStatus routeStatus = exchange.getContext().getRouteStatus(routeId);
// log.info("Route " + routeId + " Status: " + routeStatus);
String status = template.requestBody("controlbus:route?routeId=" + routeId + "&action=status", null, String.class);
log.info("Controlbus Route Status: " + status + " for route: " + routeId);
if ( (null == status) || status.equalsIgnoreCase("Stopped") ) {
exchange.getContext().addRoutes(new EndpointControlBusFileRouteBuilder(routeId));
// status = template.requestBody("controlbus:route?routeId=" + routeId + "&action=status", null, String.class);
// log.info("Controlbus Route Status: " + status + " for route: " + routeId);
} else {
log.info("Route " + routeId + " already started");
}
}
template.stop();
}
}
Do you know if there is any way to log, throw an interceptor, the input values of the called method?
my actual interceptor is
public class Interceptor {
#AroundInvoke
public Object interceptor(InvocationContext invocationcontext) throws Exception{
//Stampa prima del metodo
long startTime = System.currentTimeMillis();
log.debug("Invoked method: "+invocationcontext.getMethod().getName());
//here I would like to log also parameters.
try{
return invocationcontext.proceed();
} finally{
log.debug("End of method: " + invocationcontext.getMethod().getName());
log.debug(" duration: " + (System.currentTimeMillis() - startTime));
}
}
}
The bean is
#Interceptors({Interceptor.class})
#Stateless
public class MrBean implements MrBeanRemote, MrBeanLocal {
/**
* Default constructor.
*/
public MrBean() {
}
public void print(String in){
System.out.println("Print: " + in);
}
}
So if i call the print method with in = "print that" the interceptor should log "print that". Is it possible?
Thanks in advance
You want to log the parameters of your method, so you can use the getParameters() method on the InvocationContext :
http://docs.oracle.com/javaee/6/api/javax/interceptor/InvocationContext.html#getParameters()
I am trying to implement JNotify. but I am getting a bit weird error messages when I compiled the program. I get the sample code from this site ttp://jnotify.sourceforge.net/sample.html
as an info, JNotify is used for directory monitoring and this is how my source code looks like.
this is the content of the class watching.java
import net.contentobjects.jnotify.JNotifyListener;
import net.contentobjects.jnotify.JNotify;
public class watching{
public void watching(String s) throws Exception {
// path to watch
String path = System.getProperty(s);
// watch mask, specify events you care about,
// or JNotify.FILE_ANY for all events.
int mask = JNotify.FILE_CREATED |
JNotify.FILE_DELETED |
JNotify.FILE_MODIFIED |
JNotify.FILE_RENAMED;
// watch subtree?
boolean watchSubtree = true;
// add actual watch
int watchID = JNotify.addWatch(path, mask, watchSubtree, new Listener());
// sleep a little, the application will exit if you
// don't (watching is asynchronous), depending on your
// application, this may not be required
Thread.sleep(1000000);
// to remove watch the watch
boolean res = JNotify.removeWatch(watchID);
if (!res) {
// invalid watch ID specified.
}
}
class Listener implements JNotifyListener {
public void fileRenamed(int wd, String rootPath, String oldName,
String newName) {
print("renamed " + rootPath + " : " + oldName + " -> " + newName);
}
public void fileModified(int wd, String rootPath, String name) {
print("modified " + rootPath + " : " + name);
}
public void fileDeleted(int wd, String rootPath, String name) {
print("deleted " + rootPath + " : " + name);
}
public void fileCreated(int wd, String rootPath, String name) {
print("created " + rootPath + " : " + name);
}
void print(String msg) {
System.err.println(msg);
}
}
}
then this is the main class that named nowwatch.java
public class nowwatch
{
public static void main(String[] args) throws Exception
{
System.out.println("Hello World!");
watching hello = new watching();
hello.watching("C:/Users/Raden/Documents/Downloads");
}
}
but why did the error went like this? I had screenshot the error so that you can see it by clicking on this link
has any of you ever experience this type of error? any help would be appreciated though.
thanks
JNotify surely uses JNI to interface with the OS-dependent notification APIs. Looks like there's a bug in JNotify. Have you tried asking on the JNotify forum on SourceForge?
We had the same problems. Because we used JNA anyways, we just used the FileMonitor example from this framework. Works like a charm.
it ask for jNotify.dll file, make sure that you have placed that file to the window or in jre/bin or jdk/bin. and then try it will start working.