NLog Colored Console - asp.net

I am using NLog to log errors. Here is the Config code
<target name="console" xsi:type="AsyncWrapper" >
<target xsi:type="ColoredConsole" layout="${longdate:padding=-10}${callsite:className=false:includeSourcePath=false:methodName=false} | ${message}" >
<highlight-row condition="level >= LogLevel.Info" foregroundColor="Green" backgroundColor="NoChange"/>
</target>
</target>
I have a custom property set on the log event like
private LogEventInfo GetLogEvent(string loggerName, LogLevel level, string message, ConsoleColor color)
{
var logEvent = new LogEventInfo(level, loggerName, message);
logEvent.Properties["color"] = color;// color= any console color
}
and this sets the "color" property.(lets say "Red" here)
and I am trying to use this "color" property in the target like
<highlight-row condition="equals('${color}','Red')" foregroundColor="Red" backgroundColor="NoChange"/>
this dosent work and I tried
<highlight-row condition="equals('${event-context:item=color}','Red')" foregroundColor="Red" backgroundColor="NoChange"/>
but no luck.
Am I missing something or is there a better way of doing this? Can we use Layout renderers in this case? If yes how do we implement this?

First, since you are storing values in LogEventInfo.Properties, you should be using your second configuration example, which gets the value from event-context.
I have not used the ColoredConsoleTarget, so take this as a suggestion, not as something that I know for a fact will work.
I suspect that the NLog Condition object does not know about the ConsoleOutputColor enum. So, when you store a ConsoleOutputColor enum value in LogEventInfo.Properties, the Condition does not know that 'Red' (in the condition) refers to ConsoleOutputColor.Red. I have two suggestions:
First option: store the string value of the ConsoleOutputColor in LogEventInfo.Properties. Using ToColor might be sufficient. Something like this:
var logEvent = new LogEventInfo(level, loggerName, message);
logEvent.Properties["color"] = color.ToString();
Then, in your Condition, you should be able to compare against the ConsoleOutputColor string values (what you have in your configuration might be right, if you store the color name string as I suggested).
If that doesn't work, you could try...
Second option: store the ConsoleOutputColor value in LogEventInfo.Properties, as you are doing now, but change your condition in the config file to compare the "color" from event-context to the numeric value of the ConsoleOutputColor values. Something like this (I have not tried this so I don't know for sure that it is correct):
<highlight-row condition="equals('${event-context:item=color}','12')" foregroundColor="Red" backgroundColor="NoChange"/>
(In the ConsoleOutputColor enum, Red is 12).

Related

How do I get a value from a dictionary when the key is a value in another dictionary in Lua?

I am writing some code where I have multiple dictionaries for my data. The reason being, I have multiple core objects and multiple smaller assets and the user must be able to choose a smaller asset and have some function off in the distance run the code with the parent noted.
An example of one of the dictionaries: (I'm working in ROBLOX Lua 5.1 but the syntax for the problem should be identical)
local data = {
character = workspace.Stores.NPCs.Thom,
name = "Thom", npcId = 9,
npcDialog = workspace.Stores.NPCs.Thom.Dialog
}
local items = {
item1 = {
model = workspace.Stores.Items.Item1.Main,
npcName = "Thom",
}
}
This is my function:
local function function1(item)
if not items[item] and data[items[item[npcName]]] then return false end
end
As you can see, I try to index the dictionary using a key from another dictionary. Usually this is no problem.
local thisIsAVariable = item[item1[npcName]]
but the method I use above tries to index the data dictionary for data that is in the items dictionary.
Without a ton of local variables and clutter, is there a way to do this? I had an idea to wrap the conflicting dictionary reference in a tostring() function to separate them - would that work?
Thank you.
As I see it, your issue is that:
data[items[item[npcName]]]
is looking for data[“Thom”] ... but you do not have such a key in the data table. You have a “name” key that has a “Thom” value. You could reverse the name key and value in the data table. “Thom” = name

How to add a value to the existing element value and return it as a new value

This is the xml file.
<?xml version="1.0" encoding="UTF-8"?>
<root>
<AtcoCode> System-Start-Date= 2018-05-16T12:35:48.6929328-04:00, " ", System-End-Date = 9999-12-31, " ", 150042010003</AtcoCode>
<NaptanCode>esxatgjd</NaptanCode>
<PlateCode>
</PlateCode>
<CleardownCode>
</CleardownCode>
<CommonName>Upper Park</CommonName>
<CommonNameLang>
</CommonNameLang>
<ShortCommonName>
</ShortCommonName>
<ShortCommonNameLang>
</ShortCommonNameLang>
<Landmark>Upper Park</Landmark>
<LandmarkLang>
</LandmarkLang>
<Street>High Road</Street>
<StreetLang>
</StreetLang>
<Crossing>
</Crossing>
<CrossingLang>
</CrossingLang>
<Indicator>adj</Indicator>
<IndicatorLang>
</IndicatorLang>
<Bearing>NE</Bearing>
<NptgLocalityCode>E0046286</NptgLocalityCode>
<LocalityName>Loughton</LocalityName>
<ParentLocalityName>
</ParentLocalityName>
<GrandParentLocalityName>
</GrandParentLocalityName>
<Town>Loughton</Town>
<TownLang>
</TownLang>
<Suburb>
</Suburb>
<SuburbLang>
</SuburbLang>
<LocalityCentre>1</LocalityCentre>
<GridType>U</GridType>
<Easting>541906</Easting>
<Northing>195737</Northing>
<Co-ordinates>51.64255,0.04944</Co-ordinates>
<StopType>BCT</StopType>
<BusStopType>MKD</BusStopType>
<TimingStatus>OTH</TimingStatus>
<DefaultWaitTime>
</DefaultWaitTime>
<Notes>
</Notes>
<NotesLang>
</NotesLang>
<AdministrativeAreaCode>080</AdministrativeAreaCode>
<CreationDateTime>2006-11-06T00:00:00</CreationDateTime>
<ModificationDateTime>2010-01-16T07:58:02</ModificationDateTime>
<RevisionNumber>5</RevisionNumber>
<Modification>rev</Modification>
<Status>act</Status>
</root>
How to achieve this?
Question: Create the path range index for the status element and fetch all the documents that has status del
after fetching all the documents, you need to create the new element called currentreservationnumber under RevisionNumber element.
The value of the currentrevisionnumber will be +1 to the RevisionNumber.
I think the warning about sequential numbers is related to system-wide unique numbers/ids (like Oracle sequence), so not a worry in this case?
If you only ever have one RevisionNumber, and you can find it without a path index, you can maybe get by with element-value query on the RevisionNumber since it's already indexed.
Given that you get the document somehow, it could be as simple as:
let $doc := fn:doc ('/foo.xml')
let $rev-node := $doc/root/RevisionNumber
return xdmp:node-insert-after ($rev-node, <currentreservationnumber>{$rev-node + 1}</currentreservationnumber>)
though remember to consider locking if you are doing a big query/update. And you might need to switch to node-replace if there is already a currentreservationnumber.

How to use ASP.NET Resources in this way?

I am doing some labeling. I would like to add a resource key (s, sec) to one of my combo boxes with item[3sec, 5sec, 10sec, 30sec ...] and use it like:
Text="3<%$ Resources: myResource, s%>" to get comboBoxItem 3sec,
Text="5<%$ Resources: myResource, s%>" to get comboBoxItem 5sec ...
But I find that the server will treat this as plain text.
Do I need to define each item in a separate resource key pair?
Consider defining your resource file entry value as follows:
{0}sec
And then
String.Format(Resources.myResource.s, "3")
You can try creating your own custom expression builder. They are really powerful if you want to achieve what you have asked in your question.
Or, you can always do it using server-side code.
You could do it like this (with a DataBind() call somewhere):
Text='<%# "3" + Resources.myResource.s %>'
Edit: You can also do this from code behind. Something like this:
int[] times = new int[]{ 3, 5, 10, 30 };
foreach (int time in times)
{
string text = time.ToString() + Resources.myResource.s;
cbo.Items.Add(new ListItem(text, time.ToString()));
}
Edit 2: As per Muhammad's observation the first example doesn't work for this. I've used it for other controls, and I didn't see that for the current case it's not correct. Given this I would fill the control from code behind.

How can I tell if E4X expression has a match or not?

I am trying to access an XMLList item and convert it to am XML object.
I am using this expression:
masonicXML.item.(#style_number == styleNum)
For example if there is a match everything works fine but if there is not a match then I get an error when I try cast it as XML saying that it has to be well formed. So I need to make sure that the expression gets a match before I cast it as XML. I tried setting it to an XMLList variable and checking if it as a text() propertie like this:
var defaultItem:XMLList = DataModel.instance.masonicXML.item.(#style_number == styleNum);
if(defaultItem.text())
{
DataModel.instance.selectedItem = XML(defaultItem);
}
But it still give me an error if theres no match. It works fine if there is a match.
THANKS!
In my experience, the simplest way to check for results is to grab the 0th element of the list and see if it's null.
Here is your code sample with a few tweaks. Notice that I've changed the type of defaultItem from XMLList to XML, and I'm assigning it to the 0th element of the list.
var defaultItem:XML =
DataModel.instance.masonicXML.item.(#style_number == styleNum)[0];
if( defaultItem != null )
{
DataModel.instance.selectedItem = defaultItem;
}
OK I got it to work with this:
if(String(defaultItem.#style_number).length)
Matt's null check is a good solution. (Unless there is the possibility of having null items within an XMLList.. probably not, but I haven't verified this.)
You can also check for the length of the XMLList without casting it to a String:
if (defaultItem.#style_number.length() > 0)
The difference to String and Array is that with an XMLList, length() is a method instead of a property.

Using strings to access custom methods dynamically

I am creating a two-dimensional list that has consecutive numbers at the end of "day", for use as dataProvider for a DataGrid
i have been accessing them via the command
dg1.selectedItem.day1
dg1.selectedItem.day2
dg1.selectedItem.day3
etc...
is there any way to take the string ("day"+i) and convert it into a (what is it? variable name?)
so that i can do something along the lines of:
for(var i:Number=1; i<numFields; i++)
{
dg1.selectedIndex = i-1;
dg1.selectedItem.(mysteryFunction("day"+i)) = 42;
}
if there's a function that i could use for mysteryFunction, or what data type to use, any info would be very helpful
this is what i've been using (so tedious):
<mx:XMLList id="sched">
<field>
<day1></day1>
<day2></day2>
<day3></day3>
</field>
<field>
<day1></day1>
<day2></day2>
<day3></day3>
</field>
...
</mx:XMLList>
The "mystery function" you are looking for is as simple as indexing with brackets:
for(var i:Number=1; i<numFields; i++)
{
dg1.selectedIndex = i-1;
dg1.selectedItem["day"+i] = 42;
}
And it is called, surprisingly, an attribute.
Use an Array or if you are going to bind it (which I am kind of betting on) use ArrayCollection instead of naming these variables individually.
If the members are generated by some program, you better put all of these in one of the collection classes I mentioned above and then start the processing. It makes life easier in the long run.
E4X is the way to go when dealing with XML. The Mozilla guys have an arguably better explanation of that technology. So, if your XML is stored in a variable as:
var tree:XML = <field>
<day1></day1>
<day2></day2>
<day3></day3>
You can simply do:
tree.day1 = 42;
Why would you want this mysteryFunction()? A dataProvider object is just a collection of some Type. You know the type already, right? Read this.
Anyway, there is no such mystery function. Note, however, string concatenation with a number converts the number to a string. Try
trace("str " + 42);

Resources