Why isn't this code writing log output on my Tridion Content Delivery server? - tridion

I have a user control rendering content from a custom (non-Tridion) database. The connection string for this custom database is incorrect, and so I'm getting an SqlException when the code tries to connect.
My code is currently:
var logger =
Tridion.ContentDelivery.Web.Utilities
.LoggerFactory.GetLogger(this.GetType().ToString());
try
{
/* make a database connection - failing with SqlException */
}
catch (SqlException e)
{
logger.Error("Could not connect to database: " + e.ToString());
}
My \bin\config\logback.xml file contains:
<property name="log.pattern" value="%date %-5level %logger{0} - %message%n"/>
<property name="log.history" value="7"/>
<property name="log.folder" value="c:/tridion/log"/>
<property name="log.level" value="DEBUG"/>
...
<appender name="rollingCoreLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log.folder}/cd_core.%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>${log.history}</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${log.pattern}</pattern>
</encoder>
<prudent>true</prudent>
</appender>
...
<root level="warn">
<appender-ref ref="rollingCoreLog"/>
</root>
There's a stack of logs in C:\Tridion\log, but the most recently changed one was modified 20 minutes ago, and doesn't contain my log message text (I just did a search for "database" in notepad).
Why isn't my log output being sent to the log?

You have 2 options:
You define the root logging to "DEBUG" but this has the disadvantage that allows a huge amount of logging from all the third-party libraries that Tridion is using. Here is the snippet: <root level="DEBUG"> <appender-ref ref="rollingCoreLog"/> </root>
You define a special appender to include also the Tridion .NET logging: <logger name="Tridion.ContentDelivery" level="${log.level}"><appender-ref ref="rollingCoreLog"/></logger>
Note that in the second case you need your logger to be bound to a namespace under Tridion.ContentDelivery. Here is an example:
var logger =
Tridion.ContentDelivery.Web.Utilities.LoggerFactory.GetLogger("Tridion.ContentDelivery.MyNamespace.MyClass");
Hope this helps.
P.S.: to answer your question: because you do not have an appender for it and the root logging is set to WARN. By default, the logback.xml contains appenders only for "com.tridion" but I guess that the output of this.getType().ToString() does not start with that string.

Related

dbus api for sending GATT notification in bluez

Can someone tell me how to send GATT notifications using DBUS api's. Currently I am using bluez5.43. I am trying to register a service and send notifications. I have taken the reference of gatt-service.c which is present under the tools directory. When i look at the source code the characteristic has several characteristic methods registered with it. Out of those one is
GDBUS_ASYNC_METHOD("StartNotify", NULL, NULL, chr_start_notify)
but when i navigate to chr_start_notify,
I see the following
static DBusMessage *chr_start_notify(DBusConnection *conn, DBusMessage *msg, void *user_data)
{
return g_dbus_create_error(msg, DBUS_ERROR_NOT_SUPPORTED, "Not Supported");
}
Can anyone at least tell me is there any DBUS api for handling this, or dbus doesn't still support GATT server notifications?
I had the same issue and I found I workaround.
IF your client as enable notification upon your characteristic, this two following lines will set characteristic current value and BlueZ will handle it in stack and notify all subscribers
gatt_characteristic1_set_value(interface,value);
g_dbus_interface_skeleton_flush(G_DBUS_INTERFACE_SKELETON(interface));
You can, as an example, run a thread which call this function every X seconds, and your client will be notified every X seconds.
EDIT :
GattCharacteristic1 is a C DBus object create by gdbus-codegen from a xml file.
https://developer.gnome.org/gio/stable/gdbus-codegen.html
To help you, this is my xml file that I wrote according to BlueZ API doc.
<?xml version="1.0" encoding="UTF-8"?>
<node xmlns:doc="http://www.freedesktop.org/dbus/1.0/doc.dtd">
<interface name="org.bluez.GattCharacteristic1">
<property name="UUID" type="s" access="read" />
<property name="Service" type="o" access="read" />
<property name="Value" type="ay" access="read" />
<property name="Notifying" type="b" access="read" />
<property name="Flags" type="as" access="read" />
<method name="ReadValue">
<arg name="options" type="a{sv}" direction="in" />
<arg name="value" type="ay" direction="out" />
</method>
<method name="WriteValue">
<arg name="value" type="ay" direction="in" />
<arg name="options" type="a{sv}" direction="in" />
</method>
<method name="StartNotify"/>
<method name="StopNotify"/>
</interface>
</node>
Once you have your xml file (named org.bluez.GattCharacteristic1.xml) which describe your GATT BlueZ object, use gbus-codegen to generate a "C DBus Object"
gdbus-codegen --generate-c-code org_bluez_gatt_characteristic_interface --interface-prefix org.bluez. org.bluez.GattCharacteristic1.xml
Now add c and h files into your sources codes
The following lines show HOW I create one GATT BlueZ characteristic upon DBus
const char* char_flags[] = {"read", "write", "notify", "indicate", NULL};
GattCharacteristic1* interface = gatt_characteristic1_skeleton_new();
// dbus object properties
gatt_characteristic1_set_uuid(interface,UUID);
gatt_characteristic1_set_service(interface,service_name);
gatt_characteristic1_set_value(interface,value);
gatt_characteristic1_set_notifying(interface,notifying);
gatt_characteristic1_set_flags(interface,flags);
// get handler (for example), please read doc from gdbus-codegen provide above.
g_signal_connect(interface,
"handle_read_value",
G_CALLBACK(dbus_client_on_handle_gatt_characteristic_read_value),
NULL);
// register new interface on object
g_dbus_object_skeleton_add_interface(object,G_DBUS_INTERFACE_SKELETON(interface));
// exports object on manager
g_dbus_object_manager_server_export(server_manager,object);
Please edit flags as you need. Keep a pointer upon interface object and use lines that I provides in the first answer. GBus doc is well documented, so I hope you will find every that you need.

Unable to lookup jndi name tomcat 8.0 mybatis

I am using tomcat 8.0, mybatis 3.2.2, my application was working fine when I used datasource in mybatis-config.xml
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="oracle.jdbc.driver.OracleDriver"/>
<property name="url" value="jdbc:oracle:thin:#localhost:1521:XE"/>
<property name="username" value="uid"/>
<property name="password" value="pwd"/>
</dataSource>
</environment>
I followed the procedure and solution given in many forums, particularly stachoverflow, but it didn't help. Here are the steps I followed. I have placed mysql-connector-java-5.1.38.jar under Tomcat8.0\lib and ojdbc6.jar under WEB-INF\lib folder. I am using java 1.8. Please help to identify where I missed
server.xml under Tomcat8.0\conf
<GlobalNamingResources>
<Resource name="jdbc/MYDB"
auth=Container
type="javax.sql.DataSource"
driverClassName="oracle.jdbc.driver.OracleDriver"
username="uid"
password="pwd"
url="jdbc:oracle:thin:#localhost:1521:XE"
/>
Tomcat8.0\conf\context.xml
<Context>
<ResourceLink name="jdbc/MYDB" global="jdbc/MYDB" type="javax.sql.DataSource"/>
</Context>
web.xml within myapp/WebContent/WEB-INF/
<resource-ref>
<description>DB Connection</description>
<res-ref-name>jdbc/MYDB</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
mybatis-config.xml with JNDI name reference
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="JNDI">
<property name="data_source" value="java:comp/env/jdbc/MYDB"/>
</dataSource>
</environment>
DBUtil.java has the below code
String resource = "path of mybatis-config.xml";
InputStream inputStream;
try {
inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
But when I run the application(access the database), I get
Cause: java.sql.SQLException: Cannot create JDBC driver of class '' for connect URL 'null'
.
.
.
Caused by: java.lang.NullPointerException
at com.mysql.fabric.jdbc.FabricMySQLDriver.parseFabricURL(FabricMySQLDriver.java:97)
Please let me know where I have missed and whats the issue.
The main problem I see is that you are using a MySQL JDBC driver for an Oracle database. This is an Oracle Driver: oracle.jdbc.driver.OracleDriver and this is an oracle connection string: jdbc:oracle:thin:#localhost:1521:XE but you mention this:
I have placed mysql-connector-java-5.1.38.jar under Tomcat8.0\lib and ojdbc6.jar under WEB-INF\lib folder.
You need to place ojdbc6.jar (the JDBC driver for Oracle DB) under Tomcat8.0\lib and remove the mysql-connector-java-5.1.38.jar (a JDBC driver for MySQL DB).

Debug spring mvc view rendering time

I am currently using Spring MVC 3.x,
and using the freemarker view resolver.
Recently i have been wondering about the execution time that it takes for a view to translate into html before getting sent back as a response. I would like to do tunings if things are slow in this area, which is why i need some numbers.
In plain freemarker mode, i can actually do the simple System.currentTimeMillis() between these to find out the execution time :
long start = System.currentTimeMillis();
// this could be slow or fast depending on the caching used
Template temp = cfg.getTemplate(ftlName);
...
temp.process(model, myWriter); // depends on the writer
System.out.printf("done in %s ms", System.currentTimeMillis() - start);
But how do i do this when with spring mvc's freemaker view rendering ?
You might consider extending org.springframework.web.servlet.view.freemarker.FreeMarkerView and configuring FreeMarkerViewResolver with your custom logging view implementation.
Logging view implementation could look like this:
public class LoggingFreeMarkerView extends FreeMarkerView {
private static final transient Log log = LogFactory.getLog(LoggingFreeMarkerView.class);
#Override
protected void doRender(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception {
long start = System.currentTimeMillis();
super.doRender(model, request, response);
log.debug("Freemarker rendered " + request.getRequestURI() + " in " + (System.currentTimeMillis() - start) + " ms");
}
}
And wire the view resolver with new class:
<bean id="viewResolver" class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver" autowire="no">
<property name="viewClass" value="com.example.LoggingFreeMarkerView" />
<property name="cache" value="false" /> <!-- cache disabled for performance monitoring -->
<property name="prefix" value="" />
<property name="suffix" value=".ftl" />
<property name="contentType" value="text/html;charset=utf-8" />
<property name="exposeRequestAttributes" value="true" />
<property name="requestContextAttribute" value="base" />
</bean>
You are going to calculate just on server side merging template with data,Main problem is when freemarker executing on page ,As you know freemarker built on top of jsp page so you should bring code to jsp side to calculate execution time,
As my experience according to data size load time in freemarker is different.
if else condition also is too slow compare to jstl!
I can recommend thymeleaf for spring that allowing templates to be working prototypes on not xml style .

Spring MVC JDBC DataSourceTransactionManager: Data committed even after readonly=true

I am currently developing a Spring MVC application.I have configured a JDBC TransactionManager and I am doing declarative transaction management using AOP XML.However, even if I configure the method to run on a read-only=true, it still commits the transaction.
Database : Oracle 10g
My database-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schem...ring-beans.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="${driver}" />
<property name="url" value="${url}" />
<property name="username" value="${username}" />
<property name="password" value="${password}" />
<property name="defaultAutoCommit" value="false" />
</bean>
<bean id="txManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="mapperLocations" value="classpath:com/mybatis/mappers/*.xml" />
</bean>
<!--
the transactional advice (what 'happens'; see the <aop:advisor/> bean
below)
-->
<tx:advice id="txAdvice" transaction-manager="txManager">
<!-- the transactional semantics... -->
<tx:attributes>
<!-- all methods starting with 'get' are read-only -->
<tx:method name="get*" read-only="true" />
<!-- other methods use the default transaction settings (see below) -->
<tx:method name="*" read-only="true" rollback-for="RuntimeException"/>
</tx:attributes>
</tx:advice>
<!--
ensure that the above transactional advice runs for any execution of
an operation defined by the FooService interface
-->
<aop:config>
<aop:pointcut id="fooServiceOperation"
expression="execution(* com.service.EmployeeService.*(..))" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="fooServiceOperation" />
</aop:config>
</beans>
My controller
package com.service;
import java.util.List;
import com.mybatis.dao.EmployeeMapperInterface;
import com.spring.model.Employee;
public class EmployeeService implements EmployeeBaseService{
EmployeeMapperInterface employeeMapper;
public EmployeeMapperInterface getEmployeeMapper() {
return employeeMapper;
}
public void setEmployeeMapper(EmployeeMapperInterface employeeMapper) {
this.employeeMapper = employeeMapper;
}
#Override
public Employee getEmployeeById(long empId){
//retrieve from database
List empList = employeeMapper.getEmployeeWithId(empId);
if(empList != null && empList.size()>0){
return (Employee) empList.get(0);
}
return null;
}
#Override
public long saveEmployee(Employee employee){
long empId = 0l;
if(employee.getEmpId()==0){
empId = new Long( employeeMapper.insertEmployee(employee));
}else{
employeeMapper.updateEmployee(employee);
empId = employee.getEmpId();
}
try {
System.out.println("gonna sleep");
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
return empId;
}
How do I prevent the auto commit?I have also noticed that even if I don't put any transaction management code, the code still commits. Note, the transaction advice is however,invoked as when I put a no-rollback-for for RuntimeException and then do a 1/0, it correctly commits the data and rolls back if I put the same as rollback-for.
I have also tried out the query timeout by putting the thread on sleep, even that doesn't work, but I figure that timeout might be for an actual query, so thats fine.
Thanks in advance!
The advice read-only is only advice. It is not a requirement that the underlying transaction management system prevent writes when something is marked read-only, it is meant more as an optimization hint, saying that this method is read only, so you don't need to worry about it changing things. Some transaction managers will complain if changes are made in a read-only transaction, some will not. Generally, datasources acquired via JNDI will not. In any case, you should not rely on read-only advice preventing changes from being written back to disk.
Your options for preventing changes from being persisted are:
Mark the transaction rollback only or throw an exception having the same effect
Detach/evict the object from the transaction session before you change it
Clone the object and use the clone
DataSourceTransactionManager begins transaction with doBegin method.
From this method DataSourceUtils.prepareConnectionForTransaction called.
Inside this method you can see following code block:
if (definition != null && definition.isReadOnly()) {
try {
if (logger.isDebugEnabled()) {
logger.debug("Setting JDBC Connection [" + con + "] read-only");
}
con.setReadOnly(true);
}
catch (SQLException ex) {
So you could configure your logging framework to set log-level to DEBUG for DataSourceUtils class.
Or you could set breakpoint in this place and debug manually.
According to this article I expect that SET TRANSACTION READ ONLY will be executed on your Oracle connection.
And from Oracle docs we could see benefits which you receive in case of success:
By default, the consistency model for Oracle guarantees statement-level read consistency, but does not guarantee transaction-level read consistency (repeatable reads). If you want transaction-level read consistency, and if your transaction does not require updates, then you can specify a read-only transaction. After indicating that your transaction is read-only, you can execute as many queries as you like against any database table, knowing that the results of each query in the read-only transaction are consistent with respect to a single point in time.
The read-only behaviour is strictly driver specific. Oracle driver ignores this flag entirely. For instance the same update statements executed in Oracle will modify the database if run in read-only transaction, while in HSQL2 I was getting db level exceptions.
I know no other way than explicit rollback through api or exception to prevent commit in Oracle. Also this way your code will be portable between different drivers and databases.
The answer is on Spring MVC Mybatis transaction commit
Detailed stack traces are also available.
To summarize,
Read-only is only an advice and it guarantees nothing, and I would
really like the Spring docs to be updated about this.
whenever a query is executed in Oracle using Mybatis, it is in the context of a transaction which is automatically started,
committed(or rolled back, if execption is raised),and closed by
Mybatis.
Logging the application was a good idea and it helped me to find out how the actual transactions are started etc
.

nhibernate configure and buildsessionfactory time

I'm using Nhibernate as the OR/M tool for an asp.net application and the startup performance is really frustrating. Part of the problem is definitely me in my lack of understanding but I've tried a fair bit (understanding is definitely improving) and am still getting nowhere.
Currently ANTS profiler has that the Configure() takes 13-18 seconds and the BuildSessionFActory() as taking about 5 seconds. From what i've read, these times might actually be pretty good, but they were generally talking about hundreds upon hundreds of mapped entities...this project only has 10.
I've combined all the mapping files into a single hbm mapping file and this did improve things but only down to the times mentioned above...
I guess, are there any "Traps for young players" that are regularly missed...obvious "I did this/have you enabled that/exclude file x/mark file y as z" etc...
I'll try the serialize the configuration thing to avoid the Configure() stage, but I feel that part shouldn't be that long for that amount of entities and so would essentially be hiding a current problem...
I will post source code or configuration if necessary, but I'm not sure what to put in really...
thanks heaps!
edit (more info)
I'll also add that once this is completed, each page is extremely quick...
configuration code- hibernate.cfg.xml
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="hibernate-configuration"
type="NHibernate.Cfg.ConfigurationSectionHandler, NHibernate" />
</configSections>
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
<session-factory>
<property name="dialect">NHibernate.Dialect.MsSql2005Dialect</property>
<property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>
<property name="connection.driver_class">NHibernate.Driver.SqlClientDriver</property>
<property name="connection.connection_string_name">MyAppDEV</property>
<property name="cache.provider_class">NHibernate.Caches.SysCache.SysCacheProvider, NHibernate.Caches.SysCache</property>
<property name="cache.use_second_level_cache">true</property>
<property name="show_sql">false</property>
<property name="proxyfactory.factory_class">NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle</property>
<property name="current_session_context_class">managed_web</property>
<mapping assembly="MyApp.Domain"/>
</session-factory>
</hibernate-configuration>
</configuration>
My SessionManager class which is bound and unbound in a HttpModule for each request
Imports NHibernate
Imports NHibernate.Cfg
Public Class SessionManager
Private ReadOnly _sessionFactory As ISessionFactory
Public Shared ReadOnly Property SessionFactory() As ISessionFactory
Get
Return Instance._sessionFactory
End Get
End Property
Private Function GetSessionFactory() As ISessionFactory
Return _sessionFactory
End Function
Public Shared ReadOnly Property Instance() As SessionManager
Get
Return NestedSessionManager.theSessionManager
End Get
End Property
Public Shared Function OpenSession() As ISession
Return Instance.GetSessionFactory().OpenSession()
End Function
Public Shared ReadOnly Property CurrentSession() As ISession
Get
Return Instance.GetSessionFactory().GetCurrentSession()
End Get
End Property
Private Sub New()
Dim configuration As Configuration = New Configuration().Configure()
_sessionFactory = configuration.BuildSessionFactory()
End Sub
Private Class NestedSessionManager
Friend Shared ReadOnly theSessionManager As New SessionManager()
End Class
End Class
edit 2 (log4net results)
will post bits that have a portion of time between them and will cut out the rest...
2010-03-30 23:29:40,898 [4] INFO NHibernate.Cfg.Environment [(null)] - Using reflection optimizer
2010-03-30 23:29:42,481 [4] DEBUG NHibernate.Cfg.Configuration [(null)] - dialect=NHibernate.Dialect.MsSql2005Dialect
...
2010-03-30 23:29:42,501 [4] INFO NHibernate.Cfg.Configuration [(null)] - Mapping resource: MyApp.Domain.Mappings.hbm.xml
2010-03-30 23:29:43,342 [4] INFO NHibernate.Dialect.Dialect [(null)] - Using dialect: NHibernate.Dialect.MsSql2005Dialect
2010-03-30 23:29:50,462 [4] INFO NHibernate.Cfg.XmlHbmBinding.Binder [(null)] - Mapping class:
...
2010-03-30 23:29:51,353 [4] DEBUG NHibernate.Connection.DriverConnectionProvider [(null)] - Obtaining IDbConnection from Driver
2010-03-30 23:29:53,136 [4] DEBUG NHibernate.Connection.ConnectionProvider [(null)] - Closing connection
Try changing the logging level for the NHibernate logger. It appears that you have it set to DEBUG, which is probably fine for your app., but will cause NHibernate to do a tremendous amount of logging.
<log4net>
....
<logger name="NHibernate">
<level value="ERROR"/>
</logger>
</log4net>
Did you try to remove the cache-related code from the configuration?
Also, did you try grabbing the latest trunk versions of NHibernate and Castle?

Resources