Linq2DB Nlog or logging - sql

is there a way to log all linq2DB sql queries that are made to he database with NLog?
I cannot find any realistic example. There is something for miniprofiler, but this doesn't help me, because I have not experience with it.
pull request
example
example 2

Inside your Setup method you could turn on Trace and setup WriteTraceLine to Console.WriteLine
[SetUp]
public void Setup()
{
LinqToDB.Data.DataConnection.TurnTraceSwitchOn();
LinqToDB.Data.DataConnection.WriteTraceLine = (message, displayName) => { Console.WriteLine($"{message} {displayName}"); };
}
This will write all executed SQL Queries (together with params) to the Console

Related

Karate - How to obtain response using execution hook

I have the following feature file:
Given def query = karate.call('classpath:query/Story/FindStoryByID.js')
And def variables = { id: "xxyy" }
And request { query: '#(query)', variables: '#(variables)' }
When method POST
Then status 200
And match response.data.FindStoryByID.id != '#null'
I am currently trying to do a beforeStep in order to write whole GraphQL request (query) of the feature to a file using karate.write.
So far I have come up with this:
#Override
public boolean beforeStep(Step step, ScenarioContext context) {
if (step.getText().trim().contains("request {")) {
System.out.println(step.getText());
}
return true;
}
This successfully triggers a print, which indicates I am poking on the right direction. The problem is that I haven't still able to figure out what should I do to access a variable (query) like the one we can do on a JS/Feature file (karate.get('query');)
I am wondering if it is even possible to achieve such feat through the execution hook like this?
Thanks a lot!
Ah found it! This do the job
context.vars.get("query"));

How do I execute a new job on success or failure of Hangfire job?

I'm working on a Web API RESTful service that on a request needs to perform a task. We're using Hangfire to execute that task as a job, and on failure, will attempt to retry the job up to 10 times.
If the job eventually succeeds I want to run an additional job (to send an event to another service). If the job fails even after all of the retry attempts, I want to run a different additional job (to send a failure event to another service).
However, I can't figure out how to do this. I've created the following JobFilterAttribute:
public class HandleEventsAttribute : JobFilterAttribute, IElectStateFilter
{
public IBackgroundJobClient BackgroundJobClient { get; set; }
public void OnStateElection(ElectStateContext context)
{
var failedState = context.CandidateState as FailedState;
if (failedState != null)
{
BackgroundJobClient.Enqueue<MyJobClass>(x => x.RunJob());
}
}
}
The one problem I'm having is injecting the IBackgroundJobClient into this attribute. I can't pass it as a property to the attribute (I get a "Cannot access non-static field 'backgroundJobClient' in static context" error). We're using autofac for dependency injection, and I tried figuring out how to use property injection, but I'm at a loss. All of this leads me to believe I may be on the wrong track.
I'd think it would be a fairly common pattern to run some additional cleanup code if a Hangfire job fails. How do most people do this?
Thanks for the help. Let me know if there's any additional details I can provide.
Hangfire can build an execution chains. If you want to schedule next job after first one succeed, you need to use ContinueWith(string parentId, Expression<Action> methodCall, JobContinuationOptions options); with the JobContinuationOptions.OnlyOnSucceededState to run it only after success.
But you can create a HangFire extension like JobExecutor and run tasks inside it to get more possibilities.
Something like that:
public static JobResult<T> Enqueue<T>(Expression<Action> a, string name)
{
var exprInfo = GetExpressionInfo(a);
Guid jGuid = Guid.NewGuid();
var jobId = BackgroundJob.Enqueue(() => JobExecutor.Execute(jGuid, exprInfo.Method.DeclaringType.AssemblyQualifiedName, exprInfo.Method.Name, exprInfo.Parameters, exprInfo.ParameterTypes));
JobResult<T> result = new JobResult<T>(jobId, name, jGuid, 0, default(T));
JobRepository.WriteJobState(new JobResult<T>(jobId, name, jGuid, 0, default(T)));
return result;
}
More detailed information you can find here: https://indexoutofrange.com/Don%27t-do-it-now!-Part-5.-Hangfire-job-continuation,-ContinueWith/
I haven't been able to verify this will work, but BackgroundJobClient has no static methods, so you would need a reference to an instance of it.
When I enqueue tasks, I use the static Hangfire.BackgroundJob.Enqueue which should work without a reference to the JobClient instance.
Steve

Custom Liquibase executor combining JdbcExecutor and LoggingExecutor

I'm looking for a way to record and write all those SQL statements to an output
file which get executed while running a Liquibase migration against an empty
target database.
The idea behind this is to speed up the initialization phase of integration tests
against a test database by simply reading and executing the SQL statements from the
generated file for subsequent tests.
I had no luck using updateSQL due to different handling of changesets with
pre-conditions (e.g. changeSetExecuted resolves to true for "update" but false for
"updateSQL").
Another approach was to run the Liquibase migration first, then writing a temporary
changelog file using GenerateChangeLogCommand which is finally used by another Liquibase
instance to produce an SQL update file.
While this approach works, it a) feels a bit hacky-ish, b) the end result is not the same
as running the migration directly.
Anyway, what I've come up with is a custom implementation of JdbcExecutor which incorporates
a LoggingExecutor. The implementation looks as follows:
#LiquibaseService(skip = true)
public class LoggingJdbcExecutor extends JdbcExecutor {
private LoggingExecutor loggingExecutor;
public LoggingJdbcExecutor(Database database, Writer writer) {
loggingExecutor = new LoggingExecutor(this, writer, database);
setDatabase(database);
}
#Override
public void execute(SqlStatement sql, List<SqlVisitor> sqlVisitors) throws DatabaseException {
super.execute(sql, sqlVisitors);
loggingExecutor.execute(sql, sqlVisitors);
}
#Override
public int update(SqlStatement sql, List<SqlVisitor> sqlVisitors) throws DatabaseException {
final int result = super.update(sql, sqlVisitors);
loggingExecutor.update(sql, sqlVisitors);
return result;
}
#Override
public void comment(String message) throws DatabaseException {
super.comment(message);
loggingExecutor.comment(message);
}
}
This executor gets injected into Liquibase before update() is invoked as follows:
final String path = configuration.getUpdateSqlExportFile();
ExecutorService.getInstance().setExecutor(liquibase.getDatabase(), new LoggingJdbcExecutor(
liquibase.getDatabase(), new FileWriter(path)
));
Is this approach reasonable and future proof ? While it seems to work I'm not sure if maybe I'm
missing something and there's a better way.
Thanks

How do I configure Fluent NHibernate and Log4Net inside MSUnit Tests in VS2010

I'm trying to configure my Fluent NH app to either write the sql to the debug window or better yet to a log file from within my Unit Test project. The problem is that so far I've only been able to get it to work by putting the following lines in the individual unit test
var logconfig = new System.IO.FileInfo(#"App.config");
if (logconfig.Exists)
{
log4net.Config.XmlConfigurator.ConfigureAndWatch(logconfig);
}
I've tried to put the following in the AssemblyInfo.cs but to no avail
[assembly: log4net.Config.XmlConfigurator(Watch = true)]
What I'd really like to see happen is my sql getting logged to the log file whenever I run ANY unit tests.
P.S. - currently using ShowSql() doesn't put anything in my Debug Output window either. :(
i used a base class with a static constructor to initialize logging with success
public abstract class TestsBase
{
static TestsBase()
{
var logconfig = new System.IO.FileInfo(#"App.config");
if (logconfig.Exists)
{
log4net.Config.XmlConfigurator.ConfigureAndWatch(logconfig);
}
}
// additional stuff here
}

How to log subsonic3 sql

I'm starting to develop a new asp.net application based on subsonic3 (for queries) and log4net (for logs) and would like to know how to interface subsonic3 with log4net so that log4net logs the underlying sql used by subsonic.
This is what I have so far:
public static IEnumerable<arma_ocorrencium> ListArmasOcorrencia()
{
if (logger.IsInfoEnabled)
{
logger.Info("ListarArmasOcorrencia: start");
}
var db = new BdvdDB();
var select = from p in db.arma_ocorrencia
select p;
var results = select.ToList<arma_ocorrencium>(); //Execute the query here
if (logger.IsInfoEnabled)
{
// log sql here
}
if (logger.IsInfoEnabled)
{
logger.Info("ListarArmasOcorrencia: end");
}
return results;
}
You can use the Log property of the Provider class:
_db.Provider.Log = Console.Out;
will log your SQL statements to the console. If you want to use log4net or something similar you will have to write a small mediator class that implements TextWriter and redirects all received input to log4net.
You can get the generated sql like this:
string sql = select.GetQueryText();
Make sure you are using the version 3.0.0.4 or above.
Cheers