NLog code line logging - nlog

I am using NLog to log error messages into csv:
<target name="csv" xsi:type="File"
fileName="${basedir}/Logs/log.csv"
archiveFileName="${basedir}/Logs/Archives/log.{#####}.csv"
archiveAboveSize="10240"
archiveNumbering="Sequence"
concurrentWrites="true"
keepFileOpen="false">
<layout xsi:type="CSVLayout" delimiter="Comma" withHeader="false">
<column name="time" layout="${longdate}" />
<column name="message" layout="${message}" />
<column name="logger" layout="${logger}"/>
<column name="level" layout="${level}"/>
</layout>
</target>
How can I add a column to track the code line number?
Thank you.

Try to add ${callsite} layout renderer.
<column name="source" layout="${callsite:fileName=true}" />

Related

UI to manage one to many relationship between classes in custom module in Kentico

I have created a Clinic module within Kentico V12 with two classes: Doctor and Appointment. There is a 1 to many relationship between Doctor and Appointment. How could I display the name and surname of the doctors in the Appointment grid?
<?xml version="1.0" encoding="utf-8" ?>
<grid>
<actions>
<action name="edit" caption="$General.Edit$" fonticonclass="icon-edit" fonticonstyle="allow" />
<action name="#delete" caption="$General.Delete$" fonticonclass="icon-bin" fonticonstyle="critical" confirmation="$General.ConfirmDelete$" />
</actions>
<columns>
<column source="AppointmentPatientFirstName" caption="First name" wrap="false" localize="true">
<filter type="text" size="200" />
</column>
<column source="AppointmentPatientLastName" caption="Last name" wrap="false" localize="true">
<filter type="text" size="200" />
</column>
<column source="AppointmentPatientEmail" caption="Email" wrap="false" localize="true">
<filter type="text" size="200" />
</column>
<column source="AppointmentPatientPhoneNumber" caption="Phone Number" wrap="false" localize="true">
<filter type="text" size="15" />
</column>
<column source="Date" caption="Date" wrap="false" localize="true">
<filter type="text" size="200" />
</column>
<column source="AppointmentPatientBirthDate" caption="BirthDate" wrap="false" localize="true">
<filter type="text" size="200" />
</column>
<column source="AppointmentDoctorID" caption="Doctor ID" wrap="false" localize="true">
<filter type="text" size="200" />
</column>
</columns>
<options>
<key name="DisplayFilter" value="true" />
</options>
</grid>
Kind regards.
Appointment List: https://i.stack.imgur.com/Ft1pE.png
Using this column AppointmentDoctorID modify the XML to use a transformation like so:
<column source="AppointmentDoctorID" caption="Doctor" externalsourcename="#transform: yournamespace.doctor: {%FirstName%} {%LastName%}" wrap="false" localize="true"></column>
Check out more documentation on unigrids in the Kentico Documentation.

Liferay JSF service builder configuration error

Am newbie to Liferay. I have created one JSF portlet and added the service builder to it. Using this link Generate a Persistence Framework. After configure a service builder i have generated the source using service builder. But am getting following exception when build service of project.
Exception in thread "main" java.lang.IllegalArgumentException: No entity column exist with column database name guestbookId for entity Guestbook
[echo] at com.liferay.portal.tools.service.builder.ServiceBuilder._getEntityColumnByColumnDBName(ServiceBuilder.java:4242)
[echo] at com.liferay.portal.tools.service.builder.ServiceBuilder._getColumnLengths(ServiceBuilder.java:3857)
[echo] at com.liferay.portal.tools.service.builder.ServiceBuilder._createSQLIndexes(ServiceBuilder.java:3355)
[echo] at com.liferay.portal.tools.service.builder.ServiceBuilder.<init>(ServiceBuilder.java:796)
[echo] at com.liferay.portal.tools.service.builder.ServiceBuilder.main(ServiceBuilder.java:216)
[echo] -Dservice.tpl.spring_xml_session=com/liferay/portal/tools/service/builder/dependencies/spring_xml_session.ftl
[echo] Java HotSpot(TM) 64-Bit Server VM warning: ignoring option MaxPermSize=512m; support was removed in 8.0
[mkdir] Created dir: D:\liferay\liferay-plugins-sdk-7.0\portlets\jsfguestbook-portlet\docroot\WEB-INF\service-classes
[copy] Copied 9 empty directories to 9 empty directories under D:\liferay\liferay-plugins-sdk-7.0\portlets\jsfguestbook-portlet\docroot\WEB-INF\service-classes
[javac] Compiling 38 source files to D:\liferay\liferay-plugins-sdk-7.0\portlets\jsfguestbook-portlet\docroot\WEB-INF\service-classes
[javac] Note: Some input files use or override a deprecated API.
[javac] Note: Recompile with -Xlint:deprecation for details.
[javac] Note: Some input files use unchecked or unsafe operations.
[javac] Note: Recompile with -Xlint:unchecked for details.
[jar] Building jar: D:\liferay\liferay-plugins-sdk-7.0\portlets\jsfguestbook-portlet\docroot\WEB-INF\lib\jsfguestbook-portlet-service.jar
[delete] Deleting directory D:\liferay\liferay-plugins-sdk-7.0\portlets\jsfguestbook-portlet\docroot\WEB-INF\service-classes
BUILD SUCCESSFUL
Total time: 8 seconds
Also after built the service i have added the code as per article. I got no method is configured for following code.
public Guestbook getFirstGuestbookByName(long groupId, String name) throws SystemException {
Guestbook guestbook = null;
List<Guestbook> guestbooks = guestbookPersistence.findByName(groupId, name); // This method is not exist.
if (guestbooks != null && guestbooks.size() > 0) {
guestbook = guestbooks.get(0);
}
return guestbook;
}
My service.xml configuration is follows
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE service-builder PUBLIC "-//Liferay//DTD Service Builder 7.0.0//EN" "http://www.liferay.com/dtd/liferay-service-builder_7_0_0.dtd">
<service-builder package-path="com.liferay.docs.guestbook">
<author>muthuvignesh.k</author>
<namespace>GB</namespace>
<entity name="Guestbook" local-service="true" uuid="true">
<!-- PK fields -->
<column name="guestbookId" type="long" primary="true"></column>
<!-- Group instance -->
<column name="groupId" type="long"></column>
<!-- Audit fields -->
<column name="companyId" type="long"></column>
<column name="userId" type="long"></column>
<column name="userName" type="String"></column>
<column name="createDate" type="Date"></column>
<column name="modifiedDate" type="Date"></column>
<column name="name" type="String"></column>
<finder name="GroupId" return-type="Collection">
<finder-column name="groupId"></finder-column>
</finder>
</entity>
<entity name="Entry" local-service="true" uuid="true">
<!-- PK fields -->
<column name="entryId" type="long" primary="true"></column>
<!-- Group instance -->
<column name="groupId" type="long"></column>
<!-- Audit fields -->
<column name="companyId" type="long"></column>
<column name="userId" type="long"></column>
<column name="userName" type="String"></column>
<column name="createDate" type="Date"></column>
<column name="modifiedDate" type="Date"></column>
<column name="name" type="String"></column>
<column name="email" type="String"></column>
<column name="message" type="String"></column>
<column name="guestbookId" type="long"></column>
<finder name="G_G" return-type="Collection">
<finder-column name="groupId"></finder-column>
<finder-column name="guestbookId"></finder-column>
</finder>
</entity>
<exceptions>
<exception>GuestbookName</exception>
<exception>EntryName</exception>
<exception>EntryMessage</exception>
<exception>EntryEmail</exception>
</exceptions>
Since i have using Liferay 7.0 for this. How to overcome this.
I had a same error in 6.2. It seems that the error was in the WEB-INF/sql/indexes.sql file. An index entry was using the field that the service builder could not find (but existed in the service.xml).
I think (but I couldn't verify it) the problem was occurred by an older version of liferay maven plugin (6.2.0-ga1). By deleting the file and upgrading to version 6.2.5, service builder generated a different indexes.sql and the build was successful.
Service Builder
The issue appears to be in your service builder.
1.What stands out the most is your malformed XML. You need to close the tag.
2.Secondly in your Java code you are trying to access a finder that doesn't exist. The only finder you have defined in your hibernate file is groupId. It would look something like
return guestbookPersistence.findByGroupId(groupId);
3.To create a groupid and name find it would look similar to your entry finder.
<finder name="G_N" return-type="Collection">
<finder-column name="groupId"></finder-column>
<finder-column name="name"></finder-column>
</finder>
and your java code
return guestbookPersistence.findByG_N(groupId, name);
service.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE service-builder PUBLIC "-//Liferay//DTD Service Builder 7.0.0//EN" "http://www.liferay.com/dtd/liferay-service-builder_7_0_0.dtd">
<service-builder package-path="com.latham.data">
<author>muthuvignesh.k</author>
<namespace>GB</namespace>
<entity name="Guestbook" local-service="true" uuid="true">
<!-- PK fields -->
<column name="guestbookId" type="long" primary="true"></column>
<!-- Group instance -->
<column name="groupId" type="long"></column>
<!-- Audit fields -->
<column name="companyId" type="long"></column>
<column name="userId" type="long"></column>
<column name="userName" type="String"></column>
<column name="createDate" type="Date"></column>
<column name="modifiedDate" type="Date"></column>
<column name="name" type="String"></column>
<finder name="GroupId" return-type="Collection">
<finder-column name="groupId"></finder-column>
</finder>
<finder name="G_N" return-type="Collection">
<finder-column name="groupId"></finder-column>
<finder-column name="name"></finder-column>
</finder>
</entity>
<entity name="Entry" local-service="true" uuid="true">
<!-- PK fields -->
<column name="entryId" type="long" primary="true"></column>
<!-- Group instance -->
<column name="groupId" type="long"></column>
<!-- Audit fields -->
<column name="companyId" type="long"></column>
<column name="userId" type="long"></column>
<column name="userName" type="String"></column>
<column name="createDate" type="Date"></column>
<column name="modifiedDate" type="Date"></column>
<column name="name" type="String"></column>
<column name="email" type="String"></column>
<column name="message" type="String"></column>
<column name="guestbookId" type="long"></column>
<finder name="G_G" return-type="Collection">
<finder-column name="groupId"></finder-column>
<finder-column name="guestbookId"></finder-column>
</finder>
</entity>
<exceptions>
<exception>GuestbookName</exception>
<exception>EntryName</exception>
<exception>EntryMessage</exception>
<exception>EntryEmail</exception>
</exceptions>
</service-builder>
The tutorial you linked to is for Liferay 6.2 but your document definition is for Liferay 7. There were some very big changes between 6.2 and 7. Your code seems to be compatible with both however you should still keep that in mind.

dotnet core nlog running on Linux logs only one entry

I am running an aspnet core site on Linux using Kestrel. I have set up nlog to log to csv files. All is well in my Windows development environment, but when I run it on Linux I only get one entry in the log file. I turned on nlog tracing and found the following error in the output:
2016-09-09 07:22:46.2123 Error Error has been raised. Exception: System.IO.IOException: The file '/var/aspnetcore/CSWebSite/releases/20160909061254/logs/archives/own-log.20160908.csv' already exists.
at System.IO.UnixFileSystem.MoveFile(String sourceFullPath, String destFullPath)
at System.IO.File.Move(String sourceFileName, String destFileName)
at NLog.Targets.FileTarget.ArchiveByDate(String fileName, String pattern, LogEventInfo logEvent)
at NLog.Targets.FileTarget.ProcessLogEvent(LogEventInfo logEvent, String fileName, Byte[] bytesToWrite)
at NLog.Targets.FileTarget.FlushCurrentFileWrites(String currentFileName, LogEventInfo firstLogEvent, MemoryStream ms, List`1 pendingContinuations)
2016-09-09 07:22:46.2123 Error Error has been raised. Exception: System.IO.IOException: The file '/var/aspnetcore/CSWebSite/releases/20160909061254/logs/archives/all-log.20160907.csv' already exists.
at System.IO.UnixFileSystem.MoveFile(String sourceFullPath, String destFullPath)
at System.IO.File.Move(String sourceFileName, String destFileName)
at NLog.Targets.FileTarget.ArchiveByDate(String fileName, String pattern, LogEventInfo logEvent)
at NLog.Targets.FileTarget.ProcessLogEvent(LogEventInfo logEvent, String fileName, Byte[] bytesToWrite)
at NLog.Targets.FileTarget.FlushCurrentFileWrites(String currentFileName, LogEventInfo firstLogEvent, MemoryStream ms, List`1 pendingContinuations)
This is my nlog.config:
<?xml version="1.0" encoding="utf-8" ?>
<nlog
xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<extensions>
<!--enable NLog.Web for ASP.NET Core-->
<add assembly="NLog.Web.AspNetCore"/>
</extensions>
<targets>
<!-- https://github.com/nlog/nlog/wiki/File-target -->
<!-- http://stackoverflow.com/questions/34679727/use-nlog-in-asp-net-5-application -->
<target name="allfile" xsi:type="AsyncWrapper" queueLimit="5000" overflowAction="Discard">
<target name="allfile" xsi:type="File"
fileName="${basedir}/logs/all-logfile.csv"
archiveFileName="${basedir}/logs/archives/all-log.{#}.csv"
archiveEvery="Day"
archiveNumbering="Date"
archiveDateFormat="yyyyMMdd"
maxArchiveFiles="28"
concurrentWrites="true"
keepFileOpen="false"
encoding="utf-8">
<layout xsi:type="CSVLayout">
<column name="time" layout="${longdate}" />
<column name="logger" layout="${logger}" />
<column name="authtype" layout="${aspnet-user-authtype}" />
<column name="identity" layout="${aspnet-user-identity}" />
<column name="level" layout="${uppercase:${level}}" />
<column name="message" layout="${message} ${exception:format=ToString,StackTrace}" />
</layout>
</target>
</target>
<target name="ownfile" xsi:type="AsyncWrapper" queueLimit="5000" overflowAction="Discard">
<target name="ownfile" xsi:type="File"
fileName="${basedir}/logs/own-logfile.csv"
archiveFileName="${basedir}/logs/archives/own-log.{#}.csv"
archiveEvery="Day"
archiveNumbering="Date"
archiveDateFormat="yyyyMMdd"
maxArchiveFiles="28"
concurrentWrites="true"
keepFileOpen="false"
encoding="utf-8">
<layout xsi:type="CSVLayout">
<column name="time" layout="${longdate}" />
<column name="logger" layout="${logger}" />
<column name="authtype" layout="${aspnet-user-authtype}" />
<column name="identity" layout="${aspnet-user-identity}" />
<column name="level" layout="${uppercase:${level}}" />
<column name="message" layout="${message} ${exception:format=ToString,StackTrace}" />
</layout>
</target>
</target>
<target xsi:type="Null" name="blackhole" />
</targets>
<rules>
<!--All logs, including from Microsoft-->
<logger name="*" minlevel="Debug" writeTo="allfile" />
<!--Skip Microsoft logs and so log only own logs-->
<logger name="Microsoft.*" minlevel="Trace" writeTo="blackhole" final="true" />
<logger name="*" minlevel="Debug" writeTo="ownFile" />
</rules>
</nlog>
I have concurrent writes true and keepFileOpen false which seems necessary as kestrel forks multiple dotnet processes on Linux.
Is this a bug or is my configuration incorrect?

Liferay and relationships in it

I have a portlet, which can add/update/delete books and add authors. Moreover, you can choose existing authors when you try to add book.
And now I need to show how many books were written by each author in "author" table. How can I do it? Im a newbie in liferay and I even have no idea.
It's my service.xml
<entity name="Book" local-service="true" remote-service="true" cache-enabled="false">
<column name="bookId" type="long" primary="true" />
<column name="bookName" type="String" />
<column name="bookDescription" type="String" />
<column name="authors" type="Collection" entity="Author" mapping-table="Books_Authors" />
<finder return-type="Collection" name="bookName">
<finder-column name="bookName"></finder-column>
</finder>
</entity>
<entity name="Author" local-service="true" remote-service="true" cache-enabled="false">
<column name="authorId" type="long" primary="true" />
<column name="authorName" type="String" />
<column name="books" type="Collection" entity="Book" mapping-table="Books_Authors" />
</entity>
Service Builder is your friend.
You just need to add a finder in your book entity in service.xml. If your entity has a field named author:
<finder name="Author" return-type="Collection">
<finder-column name="author" />
</finder>
The execution of build-service will generate the methods BookUtil.findByAuthor() and BookUtil.countByAuthor().
You can implement now the corresponding methods in BookLocalServiceImpl, calling the previous, and after another run of build-serivce, they're available in your Util class. Something like
public List<Book> getByAuthor(String author) {
return getPersistence().findByAuthor(author);
}
public int countByAuthor(String author) {
return getPersistence().countByAuthor(author);
}
After the last call to build-service you can call them from your BookLocalServiceUtil.
If you just want the count, don't retrieve all the collection. If there are many records, it's a bad idea. Invoke the count instead.

How to create listerners for Custom entity in liferay?

I have created custom entity employee. Now I want to add listeners for this entity so that I can track add/edit/delete employee operations.
In Liferay for portal enitites like Blogs, Group, User etc we can add properties like
value.object.listener.com.liferay.portal.model.Group=com.smb.test.hook.listeners.GroupListener
in portal.properties via hook-plugin.
But for custom entity this approach does not seem to work.
Any help would be appreciated.
For custom entity, we need to add the listener property in service-ext.properties instead of the portal.properties file.
For my employee entity I have added following property in service-ext.properties file:
value.object.listener.com.smb.employee.model.Employee=com.smb.employee.hook.listeners.EmployeeListener
Note: We need to manually create service-ext.properties file in src folder besides the service.properties file. We could have updated service.properties but since it auto-generates our changes would be lost and hence service-ext.properties is the correct liferay approach.
Here is the location of the service-ext.properties file:
Here is my service.xml:
<service-builder package-path="com.smb.employee">
<author>Suyash</author>
<namespace>smb</namespace>
<entity name="Employee" local-service="true" remote-service="true">
<!-- PK fields -->
<column name="fooId" type="long" primary="true" />
<!-- Audit fields -->
<column name="companyId" type="long" />
<column name="userId" type="long" />
<column name="userName" type="String" />
<column name="createDate" type="Date" />
<column name="modifiedDate" type="Date" />
<!-- Other fields -->
<column name="field1" type="String" />
<column name="field2" type="boolean" />
<column name="field3" type="int" />
<column name="field4" type="Date" />
<column name="field5" type="String" />
<!-- Order -->
<order by="asc">
<order-column name="field1" />
</order>
<!-- Finder methods -->
<finder name="Field2" return-type="Collection">
<finder-column name="field2" />
</finder>
</entity>
</entity>
</service-builder>

Resources