Logging jboss without adjusting log4j.xml - jboss

We're running servers with JBoss on them and log4j for errors. I've been asked to come up with a way to log things like freememory and active thread group count so that we can monitor these without having to go through the jboss console. However, I've been told that it'd be preferred if I could do this without having to make any changes to the existing servers. My original thought was to change the log4j.xml to persist the relevant data to a database to parse out and display later, however now I really don't know.
Is there any other way, without installing a 3rd party app, to automatically grab information from a jboss server and persist it? Or should I just keep fighting to be allowed to modify the log4j xml?
Also, is this even possible? I've looked all over for examples but nowhere has specifically stated that you can use log4j to also log system stats.

Hunter;
Assuming there are no network impediments and JMX remoting has not been disabled in any way, you can remotely monitor these values using the JMX API. Here's some Groovy code to do this, but you can translate this to Java easilly.
import javax.management.*;
import javax.naming.*;
Properties p = new Properties();
p.put(Context.PROVIDER_URL, url);
p.put(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory");
p.put("jnp.disableDiscovery", "true");
ctx = new InitialContext(p);
contexts.put(url, ctx);
mbeanServer = ctx.lookup("/jmx/rmi/RMIAdaptor");
// Lookups here
Put /client/jbossall-client.jar in your classpath.
Now just scroll through JMXConsole (on a Dev server if you must) and pick the attributes and ObjectName you want to collect. For example, extending the example above, to get FreeMemory (groovy again):
import javax.management.*;
def objectName = new ObjectName("jboss.system:type=ServerInfo");
def freeMem = mbeanServer.getAttribute(objectName, "FreeMemory");
In your JMXConsole, that maps to this MBean:
and to this attribute in that MBean:
So if you set up a scheduler to collect this data from time to time, you can write it to a DB, put it in an email or whatever.
Make sense ?

Related

IBM i Access Client Solutions - Printer Output but using an API

I want to replicate the functionality of the IBM i Access Client Solutions "Printer Output" tool that is used to retrieve PDF's of spooled files from our IBM Db2 environment. Instead of a user interface, I want to replicate the functionality as an API.
I want to construct an API which takes inputs such as the filter parameters pictured below:
The output of the API would be PDF(s) of the printer output spooled files that match the parameters specified.
I figure that if I am able to access the i Access Printer Output tool, then I should be able to use my credentials to access the spool files using an API or something like that.
Where would I start in constructing something like this?
Also, are there any IBM guides that contain relevant information? I have looked but been unsuccessful. The Programmer's Toolkit is, also, not available with my version of i Access.
Also, I don't have developer roles, so if this is possible, it would need to be something that I can do with little authority within the IBM i servers and the Access client.
First off, IBM ACS is Java based. Thus everything it does can be found in the IBM Toolbox for Java, aka JTOpen aka JT400.
http://jt400.sourceforge.net/
Documentation https://www.ibm.com/docs/en/i/7.4?topic=java-toolbox
You're going to want to look at the reading a transformed spool file example
The transformation actually happens on the IBM i side, by specifying the appropriate workstation customization object, QCTXPDF in this case rather than the examples original QWPTIFFG4
// The following examples demonstrate how to set up a PrintParameterList to
// obtain different transformations when reading spooled file data. In the code
// segments that follow, assume a spooled file already exists on a server, and
// the createSpooledFile() method creates an instance of the SpooledFile class
// representing the spooled file.
// Create a spooled file
SpooledFile splF = createSpooledFile();
// Set up print parameter list
PrintParameterList printParms = new PrintParameterList();
printParms.setParameter(PrintObject.ATTR_WORKSTATION_CUST_OBJECT, "/QSYS.LIB/QCTXPDF.WSCST");
printParms.setParameter(PrintObject.ATTR_MFGTYPE, "*WSCST");
// Create a transformed input stream from the spooled file
PrintObjectTransformedInputStream is = splF.getTransformedInputStream(printParms);

Discord.py mod log setup

I was wondering how one could make a command that sets up a mod log for a certain server, or start logging in one that already exists. This will probably require a database or JSON, anything is fine, as long as I can get it to work. Any help would be appreciated.
The way I would do this is with a .txt file that would contain all of the logs. I would add a line every time an event within the guild occurred, you could configure this to whatever events you wanted.
import datetime
#client.event
async def on_member_join(member):
with open("logs.txt", "a") as logsFile:
logsFile.write("\n[{}] {} just joined the server".format(datetime.datetime.now(),
member.name))
If you are currently using the logging module for discord.py or any other libraries, you can also use it for logging your own messages, either using the same or a separate logger.

Visualize an embedded neo4j instance in a web browser using default visualization

I am using embedded Neo4j, version 3.0.3. Following this guide, I have created Neo4j/Java code. It creates a database, adds two nodes (one for java, one for scala) and adds a relationship.
package examples;
import java.io.File;
import org.neo4j.graphdb.*;
import org.neo4j.graphdb.factory.GraphDatabaseFactory;
public class HelloWorld {
public static void main(String[] args) {
GraphDatabaseFactory dbFactory = new GraphDatabaseFactory();
GraphDatabaseService db = dbFactory.newEmbeddedDatabase(new File("Test_DB"));
try (Transaction tx = db.beginTx()) {
Node javaNode = db.createNode(Tutorials.JAVA);
javaNode.setProperty("TutorialID", "JAVA001");
Node scalaNode = db.createNode(Tutorials.SCALA);
scalaNode.setProperty("TutorialID", "SCALA001");
Relationship relationship = javaNode.createRelationshipTo(scalaNode, TutorialRelationships.JVM_LANGUAGES);
relationship.setProperty("Id", "1234");
tx.success();
}
}
}
enum Tutorials implements Label {
JAVA, SCALA, SQL, NEO4J;
}
enum TutorialRelationships implements RelationshipType {
JVM_LANGUAGES, NON_JVM_LANGUAGES;
}
I program using Eclipse, so all the libraries are imported and I can just click the 'run' button on Eclipse to get the code running, and it seems to work without any issues. Upon running the code, I now have a folder Test_DB in the ~/workspace/project_name/Test_DB directory, where project_name is the name of the overall Eclipse folder. My goal is now to visualize this database in a web browser. The guide I linked to earlier shows an example of this; the user was able to look at the nodes in the web browser (see the bottom of the webpage). Unfortunately, I am using a Linux computer with Firefox, and that tutorial was in Windows, and I can't figure out how to get the visualization.
There have been a few other questions related to this. Unfortunately, some of them (such as this one) propose using software other than the default visualization. I don't own the computer and I have to go through a roundabout process to get external code installed. To be clear what I mean, this link discusses the default Neo4j browser. This is what I would like to see.
This question here directly tackles the same issue, and in fact, it uses the exact same tutorial I used! The answer proposes changing the path in the neo4j-server.properties file. Unfortunately, that file doesn't exist, and upon further analysis, it seems like Neo4j 3.0 changed the configuration naming, which I found out by reading the answer to this similar question. There is now a file conf/neo4j.conf with this information. I entered the following information in the first few lines, keeping the other settings the default:
# The name of the database to mount
dbms.active_database=Test_DB
# Paths of directories in the installation.
dbms.directories.data=/home/username/workspace/project_name/
This does not appear to work. Am I using these settings correctly? When I open the neo4j web browser after running ./bin/neo4j start and click on the database symbol in the left hand side, I see "Name: Test_DB", but it also says there are no nodes and no relationships in the database, and returning a match all query provides nothing. Is it possible for the browser to connect to my database so it can see the nodes (e.g., the two nodes in my Java code above)?
Or is it that I'm not using this code correctly; does the code somehow have to avoid quitting (i.e., replace tx.success() with something else?) to keep the data there?
Sorry about answering my own question, but I finally figured out how to do this! Here's what happens: according to the github change log for 3.0.0.RC-1:
Databases are now stored in a directory called databases under the directory specified in dbms.directories.data
So what we actually have to do is make sure our data base is in the following location:
/home/username/workspace/project_name/databases/
The issue is that when we run it in Eclipse, we get the database in the following folder:
/home/username/workspace/project_name/
Thus, the solution is to make sure the new database folder is preceded by a databases name, i.e., I would change one line to:
GraphDatabaseService db = dbFactory.newEmbeddedDatabase(new File("databases/Test_DB"));

Perl parsing a log4j log [duplicate]

We have several applications that use log4j for logging. I need to get a log4j parser working so we can combine multiple log files and run automated analysis on them. I'm not looking to reinvent the wheel, so can someone point me to a decent pre-existing parser? I do have the log4j conversion pattern if that helps.
If not, I'll have to roll our own.
I didn't realize that Log4J ships with an XML appender.
Solution was: specify an XML appender in the logging configuration file, include that output XML file as an entity into a well formed XML file, then parse the XML using your favorite technique.
The other methods had the following limitations:
Apache Chainsaw - not automated enough
jdbc - poor performance in a high performance distributed app
You can use OtrosLogViewer with batch processing. You have to:
Define you log format, you can use Log4j pattern layout parser or Log4j XmlLayout
Create java class that implements LogDataParsedListener. Method public void logDataParsed(LogData data, BatchProcessingContext context) will be called on every parsed log event.
Create jar
Run OtrosLogViewer with specifying your log processing jar, LogDataParsedListener implementation and log files.
What you are looking for is called SawMill, or something like it.
Log4j log files aren't really suitable for parsing, they're too complex and unstructured. There are third party tools that can do it, I believe (e.g. Sawmill).
If you need to perform automated, custom analysis of the logs, you should consider logging to a database, and analysing that. JDBC ships with the JdbcAppender which appends all messages to a database of your choice, but it has performance implications, and it's a bit flaky. There are other, similar, alternatives on the interweb, though (like this one).
You -can- use Log4j's Chainsaw V2 to process the various log files and collect them into one table, and either output those events as xml or use Chainsaw's built-in expression-based filtering, searching & colorizing support to slice & dice the logs.
Steps:
- Start Chainsaw V2
- Create a chainsaw configuration file by copying the example configuration file available from the Welcome tab - define one LogFilePatternReceiver 'plugin' entry for each log file that you want to process
- Start Chainsaw with that configuration
- Each log file will end up as a separate tab in the UI
- Pause the chainsaw-log tab and clear the events from that tab
- Create a new tab which aggregates the events from the various tabs by going to the 'view, crate custom expression logpanel' menu item and enter 'level >= DEBUG' in the box. It will create a new tab containing events from all of the tabs with level >= debug (which is why you cleared the chainsaw-log tab).
You can get an overview of the expression syntax used to filter, colorize and search from the tutorial (available from the Help menu).
If you don't want to use Chainsaw, you can do something similar - start a simple app that doesn't log but loads a log4j.xml config file with the 'plugin' entries you defined for the Chainsaw configuration, but also define a FileAppender with an xmllayout - all of the events received by the 'receivers' will be sent to the single appender.

Getting value from session using zk

i am configured the zk with struts 1 . i created a list and set in the session.
List<String> nameList = new ArrayList<String>();
nameList.add( "xxx" );
nameList.add( "yyy" );
nameList.add( "nnn" );
nameList.add( "ddd" );
request.getSession().setAttribute("NAMES_LIST", nameList);
now from the zul file i am trying to get the session value. How do I do that?
You have to call getNativeSession on the zk session then cast that to be a javax.servlet.http.Session which the one that struts is using.
Trying to mix zk with struts is missing the point. With zk do whatever you need to do and update the zk components and the browser will automatically be updated. Putting data into old style forms to send to the server then update the page is old style programming and less efficient than zk event driven programming where you just update the zk desktop (not bothering to think about pages) and the screen is updated. Your uses can work all day with rich behavior without ever posting a form to interact with struts.
ZK session is a wrapper object on top of HttpSession, so the access is the same. With EL, just uses sessionScope, e.g., ${sessScope['xxx']}.
In Java, just use getAttribute. To get the session object, you can invoke Sessions.getCurrent().
Hope it helps.