dotlesscss does not show errors - dotless

There's something wrong with my css because no styles are being added to my website after compilation.
How do I get dotlesscss to show errors? Regular .less shows you a nice message that's very handy.

You can do this very easily with web.config. In your dotless configuration section, add the following: logger="dotless.Core.Loggers.AspResponseLogger". This will make dotless output the errors instead of blank css.
I've included the following as an example. ("..." represents existing stuff in your web.config). In my example below cache is set to false. This is useful for debugging purposes. It should probably be set to true under normal circumstances.
<configuration>
<configSections>
...
<section name="dotless" type="dotless.Core.configuration.DotlessConfigurationSectionHandler,dotless.Core" />
</configSections>
<dotless minifyCss="false" cache="false"
logger="dotless.Core.Loggers.AspResponseLogger" />
...
</configuration>

I just faced this today in my RequestReduce project. I was getting blank less -> css transforms because there were parse errors that appeared to be going into the ether. Thanks to
this related answer How can I output errors when using .less programmatically? I was able to work out a solution where I could write the errors to the response stream. You have to create a Logger derriving from dotless.Core.Loggers.ILogger:
public class LessLogger : ILogger
{
public void Log(LogLevel level, string message)
{
}
public void Info(string message)
{
}
public void Debug(string message)
{
}
public void Warn(string message)
{
}
public void Error(string message)
{
Response.Write(message);
}
public HttpResponseBase Response { get; set; }
}
You pass this into the Configuration sent to the EngineFactory:
var engine = new EngineFactory(new DotlessConfiguration
{
CacheEnabled = false,
Logger = typeof (LessLogger)
}
).GetEngine();
For unit testing purposes I wanted to pass in my HttpResponseBase that would write the error. This is where I felt things getting ugly with some nasty casting to get a reference to my logger:
((LessLogger)((LessEngine)((ParameterDecorator)engine).Underlying).Logger).Response = response;
I hope this helps you out.

Related

Logging with XQuery

I'm using XQuery 3.0 to transform an incoming message to fit my system.
The XQuery is called from an Apache Camel Route via the transform EIP.
Example:
transform().xquery("resource:classpath:xquery/myxquery.xquery",String.class)
While the transformation works without problems it would be nice, since it's partly very complex, to be able to log some informations directly during the transformation process.
So I wanted to ask if it is possible to log "into" logback directly from XQuery?
I already searched stackoverflow and of course https://www.w3.org/TR/xquery-30-use-cases/ and other sources, but I just couldn't find any information about how to log in Xquery.
My project structure is:
Spring-Boot 2 application
Apache-Camel as Routing framework
Logback as Logging framework
Update: For the integration of XQuery in the Apache-Camel Framework I use the org.apache.camel:camel-saxon-starter:2.22.2.
Update: Because the use of fn:trace was kind of ugly I searched further and now I use the extension mechanism from Saxon to provide different logging functions which can be accessed via xquery:
For more information see the documentation: http://www.saxonica.com/documentation/#!extensibility/integratedfunctions/ext-full-J
Here is what I did for logging (tested with Saxon-HE, Camel is not mandatory, I just use it by coincidence):
First step:
Extend the class net.sf.saxon.lib.ExtensionFunctionDefinition
public class XQueryInfoLogFunctionDefinition extends ExtensionFunctionDefinition{
private static final Logger log = LoggerFactory.getLogger(XQueryInfoLogFunctionDefinition.class);
private final XQueryInfoExtensionFunctionCall functionCall = new XQueryInfoExtensionFunctionCall();
private static final String PREFIX = "log";
#Override
public StructuredQName getFunctionQName() {
return new StructuredQName(PREFIX, "http://thehandofnod.com/saxon-extension", "info");
}
#Override
public SequenceType[] getArgumentTypes() {
return new SequenceType[] { SequenceType.SINGLE_STRING };
}
#Override
public SequenceType getResultType(SequenceType[] suppliedArgumentTypes) {
return SequenceType.VOID;
}
#Override
public ExtensionFunctionCall makeCallExpression() {
return functionCall;
}
}
Second step:
Implement the FunctionCall class
public class XQueryInfoExtensionFunctionCall extends ExtensionFunctionCall {
private static final Logger log = LoggerFactory.getLogger(XQueryInfoLogFunctionDefinition.class);
#Override
public Sequence call(XPathContext context, Sequence[] arguments) throws XPathException {
if (arguments != null && arguments.length > 0) {
log.info(((StringValue) arguments[0]).getStringValue());
} else
throw new IllegalArgumentException("We need a message");
return EmptySequence.getInstance();
}
}
Third step:
Configure the SaxonConfiguration and bind it into the camel context:
public static void main(String... args) throws Exception {
Main main = new Main();
Configuration saxonConfig = Configuration.newConfiguration();
saxonConfig.registerExtensionFunction(new XQueryInfoLogFunctionDefinition());
main.bind("saxonConfig", saxonConfig);
main.addRouteBuilder(new MyRouteBuilder());
main.run(args);
}
Fourth step:
Define the SaxonConfig in your XQueryEndpoint:
.to("xquery:test.xquery?configuration=#saxonConfig");
Fifth step:
Call it in your xquery:
declare namespace log="http://thehandofnod.com/saxon-extension";
log:info("Das ist ein INFO test")
Original post a.k.a How to overwrite the fn:trace Funktion:
Thanks to Martin Honnen I tried the fn:trace function. Problem was that by default it logs into the System.err Printstream and that's not what I wanted, because I wanted to combine the fn:trace function with the Logback Logging-Framework.
So I debugged the net.sf.saxon.functions.Trace methods and came to the following solution for my project setup.
Write a custom TraceListener which extends from net.sf.saxon.trace.XQueryTraceListener and implement the methods enter and leave in a way that the InstructionInfo with constructType == 2041 (for user-trace) is forwarded to the SLF4J-API. Example (for only logging the message):
#Override
public void enter(InstructionInfo info, XPathContext context) {
// no call to super to keep it simple.
String nachricht = (String) info.getProperty("label");
if (info.getConstructType() == 2041 && StringUtils.hasText(nachricht)) {
getLogger().info(nachricht);
}
}
#Override
public void leave(InstructionInfo info) {
// no call to super to keep it simple.
}
set the custom trace listener into your net.sf.saxon.Configuration Bean via setTraceListener
Call your xquery file from camel via the XQueryEndpoint because only there it is possible to overwrite the Configuration with an option: .to("xquery:/xquery/myxquery.xquery?configuration=#saxonConf"). Unfortunately the transform().xquery(...) uses it's own objects without the possibility to configure them.
call {fn:trace($element/text(),"Das ist ein Tracing Test")} in your xquery and see the message in your log.

MEF and AssemblyCatalog / AggregateCatalog

I have a simple console app as below (un-relevant code removed for simplicity)
[ImportMany(typeof(ILogger))]
public IEnumerable<ILogger> _loggers {get;set;}
public interface ILogger
{
void Write(string message);
}
[Export(typeof(ILogger))]
public class ConsoleLogger : ILogger
{
public void Write(string message)
{
Console.WriteLine(message);
}
}
[Export(typeof(ILogger))]
public class DebugLogger : ILogger
{
public void Write(string message)
{
Debug.Print(message);
}
}
The code that initialize the catalog is below
(1) var catalog = new AggregateCatalog();
(2) catalog.Catalogs.Add(new DirectoryCatalog(AppDomain.CurrentDomain.BaseDirectory));
(3) //var catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
var container = new CompositionContainer(catalog);
var batch = new CompositionBatch();
batch.AddPart(this);
container.Compose(batch);
If the catalog is initialized trough lines 1-2, nothing got loaded into _logger
If the catalog is initialized trough line 3, both logger got loaded into _logger
What's the issue with AggregateCatalog approach?
Thanks
It should work the way you are using it.
However, on line 2 you are creating a DirectoryCatalog, and on line 3 an AssemblyCatalog. Does it work as expected if you change line two into
catalog.Catalogs.Add(new AssemblyCatalog(Assembly.GetExecutingAssembly()));
I found the problem.
It seems DirectoryCatalog(path) search only in DLL by default, and my test program was a console application. And the exports were in EXE (not DLL) so they weren't loaded.
On the other hand, AssemblyCatalog(Assembly.GetExecutingAssembly()), obviously loaded exports from current assembly(which is the EXE).
The solution is to use the other constructor of DirectoryCatalog(path, searchPattern) , and use "*.*" for second param. And it works

Examples of how to use NServiceBus with NServiceBus.Ninject-CI in ASP.NET MVC 3 solution

I would like to experiment with NServiceBus using ASP.NET MVC 3. I've got a solution with NServiceBus installed, plus NinjectMVC3 and NServiceBus.Ninject-CI. Trouble is, I have no idea how to setup NServiceBus stuff in the NinjectMVC3.cs file in App_Start.
Rather annoyingly I'm having trouble finding any examples of how to use NServiceBus.Ninject-CI (I hate it when people don't bother giving examples of how to use their stuff).
Can someone help me get started please?
Load a module like this into the kernel to provide access to the bus
public class NServiceBusModule : NinjectModule
{
public override void Load()
{
this.Bind<IBus>().ToConstant(this.CreateBus()).InSingletonScope();
}
private IBus CreateBus()
{
return NServiceBus.Configure.WithWeb()
.NinjectBuilder(this.Kernel)
... // put NServiceBus config here
.CreateBus()
.Start();
}
}
Read the NServiceBus documentation about how to configure NServiveBus:
http://docs.particular.net/nservicebus/containers/ninject
http://docs.particular.net/samples/web/asp-mvc-application/
Hopefully this will help someone. I had a lot of trouble finding sample code for getting ninject working within NServiceBus.
This code below works for me in place of the more common Castle version:
public class EndpointConfig : IConfigureThisEndpoint, AsA_Publisher, IWantCustomInitialization
{
#region IWantCustomInitialization Members
public void Init()
{
Configure
.With()
.NinjectBuilder(CreateKernel())
.XmlSerializer()
.MsmqTransport();
SetLoggingLibrary.Log4Net(XmlConfigurator.Configure);
}
protected IKernel CreateKernel()
{
var kernel = new StandardKernel();
kernel.Load<MyCustomNinjectModule>();
return kernel;
}
#endregion
}
with the ninject module being the usual format, ie:
public class MyCustomNinjectModule : NinjectModule
{
public override void Load()
{
Bind(typeof(ILogger<>)).To(typeof(Log4NetLogger<>));
...
}
}

How to use a single Log4Net instance in mutliple Nunit TestFixtures with SetUpFixture

I'm just getting into the use of Selenium Webdriver and its EventFiring so that I can log any exceptions thrown by the driver to a file or email etc.
I have got Log4Net working and my Unit Tests are running fine with Selenium.
What I am having issues with is having Log4Net create 1 log file, but for multiple test fixtures.
Here are some important classes which I think I need to show you in order to explain my issue.
public class EventLogger : EventFiringWebDriver
{
// Not sure if this is the best place to declare Log4Net
public static readonly ILog Log = LogManager.GetLogger(typeof(EventLogger));
public EventLogger(IWebDriver parentDriver) : base(parentDriver)
{
// To get Log4Net to read the configuration file on what logger to use
// To console , file, email etc
XmlConfigurator.Configure();
if (Log.IsInfoEnabled)
{
Log.Info("Logger started.");
}
}
protected override void OnFindingElement(FindElementEventArgs e)
{
base.OnFindingElement(e);
//TODO:
if (Log.IsInfoEnabled)
{
Log.InfoFormat("OnFindingElement: {0}", e);
}
}
protected override void OnElementClicked(WebElementEventArgs e)
{
base.OnElementClicked(e);
//TODO:
if (Log.IsInfoEnabled)
{
Log.InfoFormat("OnElementClicked: {0}", e.Element.GetAttribute("id"));
}
}
}
Here is my SetupFixture - which I THINK is run every time a new TestFixture class is run.
[SetUpFixture]
public class BaseTest
{
protected static readonly ILog Log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
private FirefoxProfile firefoxProfile;
private IWebDriver driver;
private EventLogger eventLogger;
public IWebDriver StartDriver()
{
Common.WebBrowser = ConfigurationManager.AppSettings["WebBrowser"];
Log.Info("Browser: " + Common.WebBrowser);
switch (Common.WebBrowser)
{
case "firefox":
{
firefoxProfile = new FirefoxProfile { AcceptUntrustedCertificates = true };
driver = new FirefoxDriver(firefoxProfile);
break;
}
case "iexplorer":
{
driver = new InternetExplorerDriver();
break;
}
case "chrome":
{
driver = new ChromeDriver();
break;
}
}
driver.Manage().Timeouts().ImplicitlyWait(Common.DefaultTimeSpan);
// Here is where I start my EventLogger to handle the events from selenium
// web driver, onClick, OnFindingElement etc.
// Is this the best way? Seems a bit messy, lack of structure
return eventLogger = new EventLogger(driver);
}
public EventLogger EventLogger
{
get { return eventLogger; }
}
}
Here is one of the many TestFixtures I have, each one based on a Selenium2 PageObjects
[TestFixture]
public class LoginPageTest : BaseTest
{
private IWebDriver driver;
private LoginPage loginPage;
[SetUp]
public void SetUp()
{
// Where I use the Log from the BaseTest
// protected static readonly ILog Log <-- top of BaseTest
Log.Info("SetUp");
driver = StartDriver();
driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(30));
loginPage = new LoginPage();
PageFactory.InitElements(driver, loginPage);
}
[Test]
public void SubmitFormInvalidCredentials()
{
Console.WriteLine("SubmitFormInvalidCredentials");
loginPage.UserName.SendKeys("invalid");
loginPage.Password.SendKeys("invalid");
loginPage.SubmitButton.Click();
IWebElement invalidCredentials = driver.FindElement(By.Id("ctl00_ctl00_ctl00_insideForm_insideForm_ctl02_title"));
Assert.AreEqual("Invalid user name or password", invalidCredentials.Text);
}
}
My Log.txt file is obviously being re-written over and over after each TestFixture is run,
How can I set up my NUnit Testing so that I only run the Log4Net once, so that I can use it in both my EventLogger and TestFixtures?
I have Googled around a lot, maybe its something simple. Do I have some design issues with the structure of my project?
Try out setting explicitly AppendToFile="True" in the log4net configuration for the FileAppender you are using:
<log4net>
<appender name="..." type="log4net.Appender....">
<appendToFile value="true" />
FileAppender.AppendToFile property
Gets or sets a flag that indicates whether the file should be appended
to or overwritten
Regarding [SetupFixture], I believe you are using it in wrong way. It not supposed to mark base class of the each TesFixture by this attribute, this looks messy. You should declare class which considered to be SetupFixture and mark it by [SetupFixture] attribute so it will be called ONCE for all TestFixtures within a given (declaration) namespace.
From NUnit documentation, SetUpFixtureAttribute:
This is the attribute that marks a class that contains the one-time
setup or teardown methods for all the test fixtures under a given
namespace. The class may contain at most one method marked with the
SetUpAttribute and one method marked with the TearDownAttribute

Plug-in Development: Creating Problem Marker for a Given Resource

I seem to be having a problem with associating a problem marker with a resource; in my case, I'm trying to create a problem marker for the editor.
To achieve this, I've tried to do the following:
public class MyEditor extends TextEditor{
private ColorManager colorManager;
public MyEditor() {
super();
...
IResource resource = (IResource) getEditorInput().getAdapter(IResource.class);
try
{
marker = resource.createMarker(IMarker.PROBLEM);
}
catch (CoreException e)
{
e.printStackTrace();
}
}
However, the problem is getEditorInput() keeps returning null. I assume I am not calling it at the right location. I thought it would be ideal to create the marker once I'm setting up the editor, but this proves otherwise.
Does anyone have any advice to obtaining the proper resource I want so that I may create the problem marker? I would like to show errors and such within the editor.
I've looked at samples online for creating the marker, but most just show methods that pass the ITextEditor object without showing where the method call is. (for example: Creating Error Marker for Compiler -- see reportError method)
Thank you.
Paul
Edit:
I have also viewed the following link regarding problem markers, but again, it calls createMarker from a resource(res, in this case), but does not show the setup for it.
See Show Syntax Errors in An Eclipse Editor Plugin
EditorInput is initialize in init method
You can override init or
public class MyEditor extends TextEditor{
private ColorManager colorManager;
public MyEditor() {
super();
...
}
public void init(IEditorSite site, IEditorInput input)
throws PartInitException {
super.init(site, input);
IResource resource = (IResource) getEditorInput().getAdapter(IResource.class);
try
{
marker = resource.createMarker(IMarker.PROBLEM);
}
catch (CoreException e)
{
e.printStackTrace();
}
}
I create a marker (including a call to getEditorInput()) from the run() method of an Action object.
public class MyAction extends Action {
...
public void run() {
...
int line = ...;
IEditorInput ei = editor.getEditorInput()
if (ei != null)
createMarkerAt(line, ei);
}
}
Addition (Following Paul's comment) How to get an Editor?
Well, In my app I am subclassing AbstractRulerActionDelegate, by overriding the createAction(ITextEditor e, IVerticalRulerInfo ri) method (which, BTW, Is a must - this method is abstract) my app can get the relevant ITextEditor object.

Resources