with using lambda I have found two style of logging for log4j2
logger.trace("Number is {}", () -> getRandomNumber());
and Second
logger.trace(()-> String.format("Number is : %s)", getRandomNumber()));
What is the best style to write log statement with respect to performance ?
Both versions should be same when trace is not enabled. For actual logging first version should be slightly faster, message templates used by both Log4j and SLF4j are more limited but parse faster than String.format( see Log4j2 using {} against using %d or %s ). Inlining message format with:
logger.trace(() -> "Number is " +getRandomNumber());
is fastest but it is bad style, unless there is only one argument, at the end of message.
Related
I'm trying to model a YAML-like DSL in Xtext. In this DSL, I need some Multiline String as in YAML.
description: |
Line 1
line 2
...
My first try was this:
terminal BEGIN:
'synthetic:BEGIN'; // increase indentation
terminal END:
'synthetic:END'; // decrease indentation
terminal MULTI_LINE_STRING:
"|"
BEGIN ANY_OTHER END;
and my second try was
terminal MULTI_LINE_STRING:
"|"
BEGIN
((!('\n'))+ '\n')+
END;
but both of them did not succeed. Is there any way to do this in Xtext?
UPDATE 1:
I've tried this alternative as well.
terminal MULTI_LINE_STRING:
"|"
BEGIN ->END
When I triggered the "Generate Xtext Artifacts" process, I got this error:
3492 [main] INFO nerator.ecore.EMFGeneratorFragment2 - Generating EMF model code
3523 [main] INFO clipse.emf.mwe.utils.GenModelHelper - Registered GenModel 'http://...' from 'platform:/resource/.../model/generated/....genmodel'
error(201): ../.../src-gen/.../parser/antlr/lexer/Internal..Lexer.g:236:71: The following alternatives can never be matched: 1
error(3): cannot find tokens file ../.../src-gen/.../parser/antlr/internal/Internal...Lexer.tokens
error(201): ../....idea/src-gen/.../idea/parser/antlr/internal/PsiInternal....g:4521:71: The following alternatives can never be matched: 1
This slide deck shows how we implemented a whitespace block scoping in an Xtext DSL.
We used synthetic tokens called BEGIN corresponding to an indent, and END corresponding to an outdent.
(Note: the language was subsequently renamed to RAPID-ML, included as a feature of RepreZen API Studio.)
I think your main problem is, that you have not defined when your multiline token is ending. Before you come to a solution you have to make clear in your mind how an algorithm should determine the end of the token. No tool can take this mental burdon from you.
Issue: There is no end marking character. Either you have to define such a character (unlike YAML) or define the end of the token in anather way. For example through some sort of semantic whitespace (I think YAML does it like that).
The first approach would make the thing very easy. Just read content until you find the closing character. The sescond approach would probably be manageable using a custom lexer. Basically you replace the generated lexer with your own implemented solution that is able to cound blanks or similar.
Here are some starting points about how this could be done (different approaches thinkable):
Writing a custom Xtext/ANTLR lexer without a grammar file
http://consoliii.blogspot.de/2013/04/xtext-is-incredibly-powerful-framework.html
I'm learning to use dajaxice, and I keep breaking things, but since only the ajax parts aren't working properly, the entire site doesn't break and generate error messages, so it's taking me forever to find my mistakes. Is there a way to track down where exactly the problem lies?
I use firebug in firefox, in the net tab, the django error messages appear under the response from the server.
Here is an ajax example:
If django / dajaxice encounters a bug in the code, a http 500 (internal server error) response is generated, which firefug highlights in red. The responses tend to be fairly large and the dajaxice responses are in html but with some scrolling the error message can always be found! I think Google Chrome offers a similar feature in developer tools.
The other handy trick is to use print statements in the dajaxice methods, for example:
#dajaxice_register
def updateText(request, objId, text):
print "updateText:: objId: %s text %s" % (objId, text)
t = TextItem.objects.get(id=objId)
t.text = text
print "updateText:: t.text: " % t.text
t.save()
json_return = simplejson.dumps({'text': text, 'objId': objId})
print "updateText:: json_return: %s" % json_return
return json_return
When running the app using ./manage.py runserver, the print statements show up immediately in the console, interspersed with the network requests to django, if one of the print statements does not apear than code execution did not get that far, or did not follow that branch of a conditional (if statement).
The print statements should be removed from your code once it is working correctly, as they will effect the speed of the app in a production environment. A longer term solution is to use the django.logging module.
I have the following string.
x = %q{ On the server side, my EJB3 application uses Spring for configuring all sorts of things. So my EJBs all look up various ApplicationContexts and use them as a sort of...well, I was going to say poor man's JNDI, but the reality is that JNDI in the J2EE environment is really a poor man's Spring. :-)
On the GUI side, I use it instead of resource injection to get access to my EJBs. That lets me test the GUI component with simple pojos. So ejb is very good technology}
I am replacing the string "ejb", case insensitive. I am doing this:
y = x.gsub(/(ejb)/i, '<em>EJB</em>')
# => " On the server side, my <em>EJB</em>3 application uses Spring for configuring all sorts of things. So my <em>EJB</em>s all look up various ApplicationContexts and use them as a sort of...well, I was going to say poor man's JNDI, but the reality is that JNDI in the J2EE environment is really a poor man's Spring. :-)\n\nOn the GUI side, I use it instead of resource injection to get access to my <em>EJB</em>s. That lets me test the GUI component with simple pojos. So <em>EJB</em> is very good technology"
I have a match in lower case: "ejb", and I am replacing with this: "<em>EJB</em>". How can I replace it without case change? I want "<em>ejb</em>".
x.gsub(/(ejb)/i, '<em>\1</em>')
You want:
gsub(/(ejb)/i, "<em>#{$1}</em>")
'test EjB123'.gsub(/ejb/i, "<em>#{$1}</em>")
=> "test <em>EjB</em>123"
You might want to try:
x.gsub!(/(ejb)/i) {|m| "<em>#{$~}<em>"}
There are a set of Special global variables set by the Pattern matching:
$~ is equivalent to ::last_match;
$& contains the complete matched text;
$` contains string before match;
$' contains string after match;
$1, $2 and so on contain text matching first, second, etc capture group;
$+ contains last capture group.
For more info:
Ruby Regex
In my Play! 2.0 application I would like to define the following languages:
# The application languages
# ~~~~~
application.langs=en-GB,de-DE,nl-NL
I also have created 3 files that ends with the corresponding language codes:
Messages.en-GB
Messages.de-DE
Messages.nl-NL
When I start the application without any request for a translated key I get the following error message:
conf/application.conf: 12: Key 'de-DE' may not be followed by token: ',' (if you intended ',' to be part of the value for 'de-DE', try enclosing the value in double quotes)
Also when trying to access a message from the Scala template I still see the same message. I request the message by the following code:
#Messages("login.page")
The above changes I have done according to the Play manual: http://www.playframework.org/documentation/2.0/JavaI18N . So I have two questions:
How can I set the default langauge and change it like in 1.2.4 (Lang.change("en-GB"))
How to access the messages from the Scala templates?
In your scala file use:
<h1>#Messages("pack.key")</h1>
And in your java file use :
String title = Messages.get("pack.key");
Don't forget to add quote around your language list : conf/application.conf
application.langs="en-GB,de-DE,nl-NL"
Changing the language is not possible in Play! 2.0, see this discussion: http://groups.google.com/group/play-framework/browse_thread/thread/744d523c169333ac/5bfe28732a6efd89?show_docid=5bfe28732a6efd89
and this ticket: https://play.lighthouseapp.com/projects/82401-play-20/tickets/174-20-i18n-add-ability-to-define-implicit-lang-for-java-api#ticket-174-4
Although, when you register multiple languages you should enclose them in double qoutes, like this:
application.langs="en-GB,de-DE,nl-NL"
And then you can access them from the scala templates like this:
#Messages.get("login.title")
So currently the default language is the language that is defined in the file messages (without any prefix!!)
Or you can just use #Messages("not.logged.in")
I have a application written in Ruby which generates a log on STDOUT. The application would be running in multiple processes but I need to collate logs generated from each of the process into a single file. Is it possible?
I read somewhere that Syslog can be used for this but I am not sure how it can be used.
You don't say what OS you need this to work on, but for Linux and Mac OS, Ruby's syslog is a good candidate. I don't know if it's implemented on Windows, but I don't think it was.
The built-in documentation is not very good, but if you look at the source or "Ruby Syslog README" you'll get a good idea how to use it.
In the past I used the following code. For your purposes you'd want to reroute your output from STDOUT to this syslog method.
require 'syslog'
def syslog(msg, level=:info)
# if msg is an array, we assume it is a cmd, message pair.
if (msg.is_a?(Array))
msg = msg.join(' => ')
end
# escape all '%' using '%%'
msg.gsub!('%', '%%')
Syslog.open($0) { |s|
case level
when :crit, :critical
s.notice(msg)
when :emerg, :emergency
s.emerg(msg)
when :alert
s.alert(msg)
when :err, :error
s.err(msg)
when :warn, :warning
s.warning(msg)
when :notice
s.notice(msg)
when :info, :information
s.info(msg)
when :debug, :debugging
s.debug(msg)
end
}
end
Check the syslog man pages for information about the various logging levels.
Syslog.open($0) tells syslog to use the entire path to your application when inserting records. You might want to shrink $0 to just the application name by using Syslog.open(File.basename($0)).
I finally decided to use log4r. It can collate logs from different processes and add them to the same log file.