[root@precision2 ~]# ./configure --libexecdir=/usr/libexec/ --prefix=/usr/
[root@precision2 ~]# make
[root@precision2 ~]# make install
domenica 2 ottobre 2011
xfce4-cpugraph-plugin on Fedora 15
This plugin isn't in Fedora repositories. You can download it from source, compile and install it. I spent 1 hours to find the correct parameters to pass to configure script...
giovedì 23 giugno 2011
JGroups and slf4j
JGroups offers a mechanism to extend its logger implemented two interface, CustomLogFactory and Log. Here are the two implementations for use slf4j.
JGroupsCustomLoggerFactory:
JGroupsCustomLog.java:
Just befor initialize JGroups, call:
JGroupsCustomLoggerFactory:
import org.jgroups.logging.CustomLogFactory;
import org.jgroups.logging.Log;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class JGroupsCustomLoggerFactory implements CustomLogFactory {
@Override
@SuppressWarnings("rawtypes")
public Log getLog(Class clazz) {
Logger logger = LoggerFactory.getLogger(LogUtils.formatClassName(clazz));
return new JGroupsCustomLog(logger);
}
@Override
public Log getLog(String category) {
Logger logger = LoggerFactory.getLogger(category);
return new JGroupsCustomLog(logger);
}
}
JGroupsCustomLog.java:
import org.jgroups.logging.Log;
import org.slf4j.Logger;
import org.slf4j.Marker;
public class JGroupsCustomLog implements Log {
private Logger logger;
public JGroupsCustomLog(Logger logger) {
this.logger = logger;
}
@Override
public boolean isFatalEnabled() {
return false;
}
@Override
public boolean isErrorEnabled() {
return logger.isErrorEnabled();
}
@Override
public boolean isWarnEnabled() {
return logger.isErrorEnabled();
}
@Override
public boolean isInfoEnabled() {
return logger.isInfoEnabled();
}
@Override
public boolean isDebugEnabled() {
return logger.isDebugEnabled();
}
@Override
public boolean isTraceEnabled() {
return logger.isTraceEnabled();
}
public String getName() {
return logger.getName();
}
public void trace(String msg) {
logger.trace(msg);
}
public void trace(String format, Object arg) {
logger.trace(format, arg);
}
public void trace(String format, Object arg1, Object arg2) {
logger.trace(format, arg1, arg2);
}
public void trace(String format, Object[] argArray) {
logger.trace(format, argArray);
}
public void trace(String msg, Throwable t) {
logger.trace(msg, t);
}
public boolean isTraceEnabled(Marker marker) {
return logger.isTraceEnabled(marker);
}
public void trace(Marker marker, String msg) {
logger.trace(marker, msg);
}
public void trace(Marker marker, String format, Object arg) {
logger.trace(marker, format, arg);
}
public void trace(Marker marker, String format, Object arg1, Object arg2) {
logger.trace(marker, format, arg1, arg2);
}
public void trace(Marker marker, String format, Object[] argArray) {
logger.trace(marker, format, argArray);
}
public void trace(Marker marker, String msg, Throwable t) {
logger.trace(marker, msg, t);
}
public void debug(String msg) {
logger.debug(msg);
}
public void debug(String format, Object arg) {
logger.debug(format, arg);
}
public void debug(String format, Object arg1, Object arg2) {
logger.debug(format, arg1, arg2);
}
public void debug(String format, Object[] argArray) {
logger.debug(format, argArray);
}
public void debug(String msg, Throwable t) {
logger.debug(msg, t);
}
public boolean isDebugEnabled(Marker marker) {
return logger.isDebugEnabled(marker);
}
public void debug(Marker marker, String msg) {
logger.debug(marker, msg);
}
public void debug(Marker marker, String format, Object arg) {
logger.debug(marker, format, arg);
}
public void debug(Marker marker, String format, Object arg1, Object arg2) {
logger.debug(marker, format, arg1, arg2);
}
public void debug(Marker marker, String format, Object[] argArray) {
logger.debug(marker, format, argArray);
}
public void debug(Marker marker, String msg, Throwable t) {
logger.debug(marker, msg, t);
}
public void info(String msg) {
logger.info(msg);
}
public void info(String format, Object arg) {
logger.info(format, arg);
}
public void info(String format, Object arg1, Object arg2) {
logger.info(format, arg1, arg2);
}
public void info(String format, Object[] argArray) {
logger.info(format, argArray);
}
public void info(String msg, Throwable t) {
logger.info(msg, t);
}
public boolean isInfoEnabled(Marker marker) {
return logger.isInfoEnabled(marker);
}
public void info(Marker marker, String msg) {
logger.info(marker, msg);
}
public void info(Marker marker, String format, Object arg) {
logger.info(marker, format, arg);
}
public void info(Marker marker, String format, Object arg1, Object arg2) {
logger.info(marker, format, arg1, arg2);
}
public void info(Marker marker, String format, Object[] argArray) {
logger.info(marker, format, argArray);
}
public void info(Marker marker, String msg, Throwable t) {
logger.info(marker, msg, t);
}
public void warn(String msg) {
logger.warn(msg);
}
public void warn(String format, Object arg) {
logger.warn(format, arg);
}
public void warn(String format, Object[] argArray) {
logger.warn(format, argArray);
}
public void warn(String format, Object arg1, Object arg2) {
logger.warn(format, arg1, arg2);
}
public void warn(String msg, Throwable t) {
logger.warn(msg, t);
}
public boolean isWarnEnabled(Marker marker) {
return logger.isWarnEnabled(marker);
}
public void warn(Marker marker, String msg) {
logger.warn(marker, msg);
}
public void warn(Marker marker, String format, Object arg) {
logger.warn(marker, format, arg);
}
public void warn(Marker marker, String format, Object arg1, Object arg2) {
logger.warn(marker, format, arg1, arg2);
}
public void warn(Marker marker, String format, Object[] argArray) {
logger.warn(marker, format, argArray);
}
public void warn(Marker marker, String msg, Throwable t) {
logger.warn(marker, msg, t);
}
public void error(String msg) {
logger.error(msg);
}
public void error(String format, Object arg) {
logger.error(format, arg);
}
public void error(String format, Object arg1, Object arg2) {
logger.error(format, arg1, arg2);
}
public void error(String format, Object[] argArray) {
logger.error(format, argArray);
}
public void error(String msg, Throwable t) {
logger.error(msg, t);
}
public boolean isErrorEnabled(Marker marker) {
return logger.isErrorEnabled(marker);
}
public void error(Marker marker, String msg) {
logger.error(marker, msg);
}
public void error(Marker marker, String format, Object arg) {
logger.error(marker, format, arg);
}
public void error(Marker marker, String format, Object arg1, Object arg2) {
logger.error(marker, format, arg1, arg2);
}
public void error(Marker marker, String format, Object[] argArray) {
logger.error(marker, format, argArray);
}
public void error(Marker marker, String msg, Throwable t) {
logger.error(marker, msg, t);
}
@Override
public void fatal(String msg) {
logger.error(msg);
}
@Override
public void fatal(String msg, Throwable throwable) {
logger.error(msg, throwable);
}
@Override
public void trace(Object msg) {
logger.trace(msg.toString());
}
@Override
public void trace(Object msg, Throwable throwable) {
logger.trace(msg.toString(), throwable);
}
@Override
public void setLevel(String level) {
}
@Override
public String getLevel() {
return "INFO";
}
}
Just befor initialize JGroups, call:
try {
System.setProperty(Global.CUSTOM_LOG_FACTORY, "package.JGroupsCustomLoggerFactory");
jChannel = new JChannel();
jChannel.connect("channel-ver-3.0");
martedì 10 maggio 2011
Hibernate with Guice and a little of AOP to manage transaction.
What do you think abount @Transactional annotation? I used it with spring framework on service class to manage transaction into and intra service call.
It's a very elegant and easy way to manage transactions.
I've started working on a new project and I decided to use Guice as Dependency Injection framework, IMHO more lite and easy than Spring, and Hibernate
but I would like to continue to use the @Transactional annotation on my service class.
I didn't found anything good to use and I decided to use a little of AOP to recreate this functionality.
Let's started with order, I would like that:
1) When I call a method on a service class, the operations in this method belong to a single transaction.
2) If the caller of the method 1) has a transaction, the thansanction must is the parent (caller) transaction.
In practice the "Required" attribute of EBJ's Transactional parameter, see Required Attribute
This is the first case:
And this the second one:
I'm going to use AOP and Guice to set a Method Interceptor that check is the called method has a transaction, and in case of not, create a new one and link it to thread with ThreadLocal class. I create also an annotation that identify che class and method subject and not subject to this check:
A) The Transactional Annotation:
The NoTransactional annotation, that mark the non-transactional method on a class marked as transactional:
The implementation of this interceptor:
I'm using Jersey with Guice, and I use the @Transactional annotation also on webresources. Es:
Note that to let Guice istantiate the webresource, in addition to configuration needed by jersey-guice module, the @Inject must present on constructor's class.
It's a very elegant and easy way to manage transactions.
I've started working on a new project and I decided to use Guice as Dependency Injection framework, IMHO more lite and easy than Spring, and Hibernate
but I would like to continue to use the @Transactional annotation on my service class.
I didn't found anything good to use and I decided to use a little of AOP to recreate this functionality.
Let's started with order, I would like that:
1) When I call a method on a service class, the operations in this method belong to a single transaction.
2) If the caller of the method 1) has a transaction, the thansanction must is the parent (caller) transaction.
In practice the "Required" attribute of EBJ's Transactional parameter, see Required Attribute
This is the first case:
And this the second one:
I'm going to use AOP and Guice to set a Method Interceptor that check is the called method has a transaction, and in case of not, create a new one and link it to thread with ThreadLocal class. I create also an annotation that identify che class and method subject and not subject to this check:
A) The Transactional Annotation:
|
The NoTransactional annotation, that mark the non-transactional method on a class marked as transactional:
|
The implementation of this interceptor:
|
I'm using Jersey with Guice, and I use the @Transactional annotation also on webresources. Es:
|
Note that to let Guice istantiate the webresource, in addition to configuration needed by jersey-guice module, the @Inject must present on constructor's class.
giovedì 28 aprile 2011
Jersey, @RolesAllowed annotation and 403 Forbidden
I spent last three hours to understand why I always get 403 Forbidden from a secured JAX-RS resource with @RolesAllowed...
After checking the params of Jersey Servlet:
I proceeded to debug the filter under the hood, RolesAllowedResourceFilterFactory, and I noticed that UserPrincipal was null!
What I'd forgotten was to secured the resources with security-constraint:
In role-name you've to insert all the roles that you're going to use in @RolesAllowed.
Good night!
After checking the params of Jersey Servlet:
<init-param>
<param-name>com.sun.jersey.spi.container.ResourceFilters</param-name>
<param-value>com.sun.jersey.api.container.filter.RolesAllowedResourceFilterFactory</param-value>
</init-param>
I proceeded to debug the filter under the hood, RolesAllowedResourceFilterFactory, and I noticed that UserPrincipal was null!
What I'd forgotten was to secured the resources with security-constraint:
<security-constraint>
<web-resource-collection>
<web-resource-name>Protected Area</web-resource-name>
<url-pattern>/resources/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>admin</role-name>
<role-name>user</role-name>
</auth-constraint>
</security-constraint>
In role-name you've to insert all the roles that you're going to use in @RolesAllowed.
Good night!
domenica 20 febbraio 2011
Expose Apache Tomcat statistics on Cacti
Cacti is an extremly usefully tool to plot any parameters on a system.
This came out with defaults sensors for SO and Networking in general, I tried to use cacti to plot some interesting parameters about JVM and Tomcat.
I use the jmxProxy servlet came with manager webapp from tomcat's distribution to get the value of some attributes from the MBean Server.
Let we start with trace the Request Count, Error Count and Processing Time on AJP port, I do it on a Fedora 13 machine:
I hope this help to learn cacti, which hasn't a very flat learning curve.
This came out with defaults sensors for SO and Networking in general, I tried to use cacti to plot some interesting parameters about JVM and Tomcat.
I use the jmxProxy servlet came with manager webapp from tomcat's distribution to get the value of some attributes from the MBean Server.
Let we start with trace the Request Count, Error Count and Processing Time on AJP port, I do it on a Fedora 13 machine:
- Requirements
- Default Tomcat installation with manager webapp.
- Default Cacti installation.
- Set the user with manager role in tomcat-users.xml:
- This is a piece of my TOMCAT_HOME/conf/tomcat-users.xml:
<tomcat-users> <role rolename="manager"/> <user username="manager" password="changethispassword" roles="manager"/> .... </tomcat-users>
- Check the jmxProxy servlet, point your browser to http://localhost:8080/manager/jmxproxy/?qry=Catalina:type=GlobalRequestProcessor,name=http-8080 and check the result page, this is an example:
OK - Number of results: 1 Name: Catalina:type=GlobalRequestProcessor,name=http-8080 modelerType: org.apache.tomcat.util.modeler.BaseModelMBean bytesSent: 168065 bytesReceived: 340 processingTime: 5310 errorCount: 0 maxTime: 3214 requestCount: 16
- Create the script to get the output of jmxProxy servlet as input for Cacti:
- Log on the machine as cacti user and create the file CACTI_HOME/scripts/get_tomcat_globalrequestprocessor.sh:
#!/bin/bash OPTTIONS="--user $3:$4 -f -S http://$1:$2/manager/jmxproxy/?qry=Catalina:type=GlobalRequestProcessor,name=$5" OUTPUT=$(curl $OPTTIONS 2>/dev/null) PT=$(printf "$OUTPUT" | grep -e "^processingTime: " | grep -oEi 'processingTime: ([0-9]*)' | sed "s/processingTime: /processingtime:/g") EC=$(printf "$OUTPUT" | grep -e "^errorCount: " | grep -oEi 'errorCount: ([0-9]*)' | sed "s/errorCount: /errorcount:/g") RC=$(printf "$OUTPUT" | grep -e "^requestCount: " | grep -oEi 'requestCount: ([0-9]*)' | sed "s/requestCount: /requestcount:/g") echo $PT $EC $RC
- Change it's permission: chmod 775 scripts/get_tomcat_globalrequestprocessor.sh
- Check the script: ./scripts/get_tomcat_globalrequestprocessor.sh localhost 8080 manager changethispassword http-8080
-bash-4.1$ ./get_tomcat_globalrequestprocessor.sh localhost 8080 manager changethispassword http-8080 processingtime:73631 errorcount:2 requestcount:18253 -bash-4.1$
- Log on the machine as cacti user and create the file CACTI_HOME/scripts/get_tomcat_globalrequestprocessor.sh:
- Configure Cacti to plot this value:
- Open Cacti and create a new Data Input Method. Type in the name field Tomcat GlobalRequestProcessor,
select Script/Command as Input Type and cut&paste the script call in Input String <path_cacti>/scripts/get_tomcat_globalrequestprocessor.sh <host> <port> <username> <password> <name>.
The name in the script wrapped between < and > are parameters that are replaced with the values came from Data Sources view (see later). Click create.
- Complete the Data Input Method specifying the input and output of script. Add in input field the five descriptions of input defined for the script and add in output fields list the four output value of the script (with a short description and leave check the field Update RRD File):
- errorcount
- processingtime
- requestcount
- Add a new Data Source. Select None in the "Selected Data Template" field and an host. I've created previously a devices called Java Virtual Machine to attach all my jvm's graph, but isn't necessary, is only for ordering graph.
Click Create and complete the Data Source with a name (Tomcat http-8080 Global Request Processor) a Data Source Path (/localhost_tomcat_globalrequestprocessor_91.rrd ) and select the just created Data Input Metod (Tomcat Global Request Processor). Leave Associated RRS's, Step and Data Source Active with default value and click Create.
Cacti has saved the DataSource and now ask for Data Source Item. In this section we have to define all data parameters that come out with Data Input Methods and specify its type (http://www.cacti.net/downloads/docs/html/templates.html Table 13-2). Start with processingtime, that is a COUNTER
Complete the Data Source Item with other two Data Source Item, all as COUNTER type and Maximum Value 0. Complete also the Custom Data section with input value that script needs.
- Create the Graph. Click on Add in Graph Management and select None as Template and an host. Click Create and insert the graph name, leaving all fields with default value. Click on Create.
Add the three Graph Items. Click Add on Graph Items, select the first our data source (Tomcat Global Request Processor (errorcount)), select a color, AREA as Graph Item Type and MAX as Consolidation Function.
You can also add Items that display the average/max/min/last value of sensors. I added Avg and Last values for each items.
- The result
- Open Cacti and create a new Data Input Method. Type in the name field Tomcat GlobalRequestProcessor,
Troubleshooting
When your graph don't appear try to do all the step that cacti do to display the graph:
- Check the script's paramenters that cacti use. Go in System Utility -> View Poller Cache and write down the Script call in Details Field. Check the parameters order and try to execute the script on the shell. Check the output.
- Check data samples in RRD file. Use the rddtool dump command to see the file content and check if your samples are out of range (if MIN or MAX aren't zero):
-bash-4.1$ rrdtool dump /usr/share/cacti/rra/localhost_tomcat_globalrequestprocessor_91.rrd | less
- Check the ERROR: the RRD does not contain an RRA matching the chosen CF This error means that the statistics collected from rrd don't match the type of Consolidation Function selected on Graph Items (Console -> Graph Management -> (Edit) -> Graph Items). To see which statistics are collected by rrd, open the rrd file with rrdtool dump (as above) and see the cf element of rra node.
- Enhancement
In this graph I don't use the template for Data Source/Graph, but if you have to create the same graph for multiple machines, creating template is the right choose.
I hope this help to learn cacti, which hasn't a very flat learning curve.
Iscriviti a:
Post (Atom)