log4j.properties
log4j.rootLogger=ON, A1
log4j.logger.org.apache.jsp=DEBUG
log4j.appender.A1=org.apache.log4j.FileAppender
log4j.appender.A1.File=test.log
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=[%d{yyyy-MM-dd HH:mm:ss}] - %m%n
test.java
package ch15;
import org.apache.log4j.Logger;
public class test
{
static Logger logger = Logger.getLogger(test.class);
public static void main(String[] args)
{
makeLog();
}
public static String makeLog()
{
logger.debug("test");
return "YES";
}
}
When I compile this java file and execute, Log File created Normally.
[2013-05-10 16:53:24] - test
But when I intend to use this class file in JSP like below, there's no Log at all.
<jsp:useBean id="t" class="ch15.test" />
<%=t.makeLog()%>
I think JSP call test class successfully because browser displays "YES".
But no log written...
Can you help me?
I'm in trouble for a week...:(
Related
I have a custom Logger that internally uses the jboss logger:
#Dependent
class LogImpl implements Log { //LogImpl & Log are custom
#Inject
Logger sink; // this is jboss logger
...
}
I inject Log wherever it is required:
class MyService {
#Inject
Log log;
}
Calls to log.debug(...), log.info(...) etc. on the log prints LogImpl as the logger name/category in the logs. What I need logged as the logger name/category is the name of the class where #Log is injected. In the example about, I need the logger name to be printed as MyService and not LogImpl.
Figured it out. Used a Producer to instantiate the custom log. InjectionPoint is used to get the class name of the object where Log in #Injected .
#ApplicationScoped
public class LogProducer {
#Produces
#Dependent
Log createLog(InjectionPoint injectionPoint) {
return new LogImpl(injectionPoint.getMember().getDeclaringClass().getCanonicalName());
}
}
class LogImpl implements Log {
private final Logger sink;
public LogImpl(String name) {
this.sink = Logger.getLogger(name); // Manual instantiation instead of #Inject. The producer calls this constructor with the correct log/category name.
}
...
}
I want to write to log inside static class in Groovy in JMeter. I can print to terminal inside and outside of class with println or System.out.println. How to do the trick with log? In code below all works except log.warn inside class, give error:
Script53.groovy: 13: Apparent variable 'log' was found in a static scope but doesn't refer to a local variable, static field or class. Possible causes:
You attempted to reference a variable in the binding or an instance variable from a static context.
You misspelled a classname or statically imported field. Please check the spelling.
You attempted to use a method 'log' but left out brackets in a place not allowed by the grammar.
Code:
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
class CalcMain {
static void main(def args) throws Exception {
ScriptEngineManager factory = new ScriptEngineManager();
ScriptEngine engine = factory.getEngineByName("groovy");
println ("testing 1");
System.out.println ("testing 2");
log.warn("warn2");
}
}
OUT.println("testing 4");
println("testing 5");
log.warn("warn 1");
CalcMain test1 = new CalcMain();
test1.main();
I tried web search but could not find an answer.
You can use Groovy #Log4j annotation:
import groovy.util.logging.Log4j
#Log4j
class CalcMain {
static void main(def args) throws Exception {
// some code
log.info "hello there"
}
}
Another option is to send log as parameter to static method:
static void main(org.slf4j.Logger log) throws Exception {
Call method:
test1.main(log);
I've read https://www.blazemeter.com/blog/top-8-jmeter-java-classes-you-should-be-using-with-groovy/ where it is advised to use log variable but also gives link to Logger class. I've tried to play with Logger class and it works:
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
class CalcMain {
static void main(def args) throws Exception {
ScriptEngineManager factory = new ScriptEngineManager();
ScriptEngine engine = factory.getEngineByName("groovy");
final Logger logger = LoggerFactory.getLogger(CalcMain.class);
logger.warn("My warning");
}
}
CalcMain test1 = new CalcMain();
test1.main();
I'm using a Java library to list all files/directory in a remote http URL:
import java.io.IOException;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
public class Sample {
public static void main(String[] args) throws IOException {
Document doc = Jsoup.connect("http://howto.unixdev.net").get();
for (Element file : doc.select("td.right td a")) {
System.out.println(file.attr("href"));
}
}
}
I'd need to do the equivalent thing with a Groovy script (as part of a Jenkins job) but I couldn't find any example of it, except for file system listing. Any help?
Thanks!
i'm actually trying to run a keyword from imported test library written in java (RF 3.0.2 , Jython 2.7.1rc3 )
import org.apache.log4j.Logger;
public class Sample
{
private static final Logger logger = Utils.getLogger(Sample.class);
#RobotKeyword("Print Message")
#ArgumentNames({"message"})
public void printMessage(String message)
{
logger.info("I'm inside");
}
}
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
public class Utils
{
public static final Logger logger = getLogger(Utils.class);
public static Logger getLogger(Class<?> clazz)
Logger logger = Logger.getLogger(className.getClass());
PropertyConfigurator.configure("/src/main/resources/log4j.properties");
return logger;
}
log4j.properties :
log4j.rootLogger=DEBUG, Stdout, file
log4j.appender.Stdout=org.apache.log4j.ConsoleAppender
log4j.appender.Stdout.Target=System.out
log4j.appender.Stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.Stdout.layout.conversionPattern=%d %-5p [%t] %F:%L %m%n
log4j.appender.Stdout.ImmediateFlush=true
log4j.appender.Stdout.follow=true
With this setup i'm able to see log after test execution in robot framework test report but it would be very helpful if i can see logs during test execution as if i was calling log to console keyword.
is There a way to do this ?
You can use listener interface http://robotframework.org/robotframework/latest/RobotFrameworkUserGuide.html#listener-interface to get real time execution information. In docs there is a sample script.
This is used in RED Robot Editor to get execution status,debug information etc. - source can be found:
TestRunnerAgent.py
In a JSF 2.2 application, I want to build a war file for testing with Selenium. In that webtest.war, I want to replace a central class, called the NodeCache, with a mock version, called the WebtestNodeCache, to keep the database and other external dependencies out of the tests.
NodeCache is a managed bean:
#javax.faces.bean.ManagedBean(name = NodeCache.INSTANCE)
#javax.faces.bean.ApplicationScoped
public class NodeCache {
public static final String INSTANE = "nodecache";
// ...
}
To sneak in WebtestNodeCache, I use a ServletContextListener like this:
public class WebtestContextListener implements ServletContextListener {
#Override
public void contextInitialized(ServletContextEvent event) {
WebtestNodeCache nodeCache = new WebtestNodeCache();
ServletContext context = event.getServletContext();
context.setAttribute(NodeCache.INSTANCE, nodeCache);
}
#Override
public void contextDestroyed(ServletContextEvent sce) {}
}
In normal builds, WebtestContextListener and WebtestNodeCache are excluded from the war file, in test builds, they are included.
This seems to work: when I log in, I get dummy nodes from the WebtestNodeCache.
Is this a reliable way to replace a bean in application context or did I just get lucky?
Is there a better way to sneak in test dummies?
Using both an #ManagedBean annotation and a Listener to replace the object did not work. The code was always using the unmocked production code managed bean.
Defining a new #ManagedBean with the same name is an error and prevents deployment.
I ended up with this:
Put the #ManagedBean annotation with the same name on both the real bean and its mock.
When building, only include the mocks when building the webtest.war, but not in the regular build.
When building, have the build script (Gradle in my case) copy and filter the sources, looking for a special comment behind the #ManagedBean declaration in the production code and taking out these lines to remove the #ManagedBean declaration on the production code so that only the ones in the mock remains.
So the original NodeCache looks like this now:
#javax.faces.bean.ManagedBean(name = NodeCache.INSTANCE) // webtest:remove
#javax.faces.bean.ApplicationScoped // webtest:remove
public class NodeCache {
public static final String INSTANE = "nodecache";
// ...
}
and the mocked version has the same annotations, just without the comment:
#javax.faces.bean.ManagedBean(name = NodeCache.INSTANCE)
#javax.faces.bean.ApplicationScoped
public class WebtestNodeCache extends NodeCache {
// ...
}
Here is the relevant part of the Gradle build script:
boolean isWebtest = false
gradle.taskGraph.whenReady { taskGraph ->
isWebtest = taskGraph.hasTask(compileWebtestWarJava);
}
task copySrc(type: Copy) {
from "src"
into "${buildDir}/src"
outputs.upToDateWhen {
// Always execute this task so that resources do or don't get filtered
// when switching between normal war file and webtests.
false
}
filter { String line ->
isWebtest && line.contains("webtest:remove") ? null : line;
}
}
This solves the problem for me. Hope someone else finds it useful.