I have verified that adding UseAbpTimeZone
to my application initialization does seem to solve the issue in the /audit-logs
page and it now shows the correct local time:
Still, it's not clear to me when to have UseAbpTimeZone
or not (I couldn't find any documentation on it besides your article).
The inconsistency shown in my previous post does seem like a bug... 🤔
Hi there.
I have migrated my application to ABP 9.2.0 and applied the migrations that updated all timestamp columns in the database to type timestamp without time zone
. I'm using both Npgsql.EnableLegacyTimestampBehavior
and AbpClockOptions.Kind = DateTimeKind.Utc
. With this, I believe now I have the correct time zone configurations both in application and database according to your instructions.
With that said, I still observe the issue I reported initially, where the time displayed in the audit logs page is incorrect, ignoring the time zone settings (application or account). Here are some screenshots:
/audit-logs
page, showing UTC time (❌ incorrect)
AbpAuditLogs
table, storing UTC time (✅ correct)
/Account/SecurityLogs
page, showing local time (✅ correct)
Sorry for the delay on this. I think it's important to explain in more details my concern regarding the correct time zone settings.
When we initially migrated to PostgreSQL, the migration guide didn't include the instruction to use the EnableLegacyTimestampBehavior
setting. That means that when we followed the old version of the guide, we got the same error reported here, and in this same thread you can see that the solution is to set AbpClockOptions.Kind
to DateTimeKind.Utc
to fix the error, so that's what we did and it worked.
So now that the migration guide has been updated to include the EnableLegacyTimestampBehavior
setting, the AbpClockOptions
setting we used seems no longer needed.
However, if I try to include the EnableLegacyTimestampBehavior
setting now, that results in changes to all timestamp columns in the DB (migrations) since this setting controls the type for these columns. For example:
// ...
migrationBuilder.AlterColumn<DateTime>(
name: "DeletionTime",
table: "AbpUsers",
type: "timestamp without time zone",
nullable: true,
oldClrType: typeof(DateTime),
oldType: "timestamp with time zone",
oldNullable: true);
// ...
I have not applied this migration since I'm not sure if it's the right thing to do in this case.
Considering this situation, what would be the recommended course of action? I think that before I can reliably report any problem related to time zone, first I need to ensure everything is correct in my application and database.
Hi,
I see that there were a bunch of changes related to time zones in 9.2.0, so I updated to it to test and the issue I described above still persists in 9.2.0. The article you linked is the same one I linked.
Also, I would appreciate if you could confirm the correct settings to use in our case.
Thanks!
Hi there.
We have identified an inconsistency in the audit logs page (/audit-logs
), where the time shown in the log entries is always fixed to the value saved in the database (UTC), so any time zone setting is ignored in this page (host time zone or user account time zone setting).
This does not happen in the security logs (/Account/SecurityLogs
) where I can verify that it correctly displays the time based on the time zone setting.
Is this intended or a bug?
For added context, we are currently using the following settings related to the time zone:
Npgsql.EnableLegacyTimestampBehavior
enabled, since we are using PostgreSQL (as instructed here).AbpClockOptions.Kind
set to DateTimeKind.Utc
(as instructed here).Should both of these settings be used at the same time? I just want to ensure we are configuring time zones correctly in the application.
Awesome, thank you.
Thanks, @maliming. This seems to solve the issue.
From my understanding looking at GitHub these fixes will be available in version 9.3, is that right? I just want to confirm that it will be safe to remove these once that version is out and we upgrade to it.
Thank you.
Hi, @maliming. I've tried doing the override you mentioned, but it doesn't seem to make a difference.
I managed to narrow it down and I've created a fresh project that reproduces the issue. You should receive the code in your email.
Here are the steps to reproduce:
Here's an image demonstrating the issue on the sample project:
We are having an odd issue with the feature check where a feature can be considered both enabled and disabled depending on where it's checked.
For instance, we have a feature check on the menu contributor to only show the corresponding menu if the feature is enabled:
if (context.Menu.Name == StandardMenus.Main && await featureChecker.IsEnabledAsync(MyDefinitionProvider.MyFeature))
{
// this correctly shows or hides the menu depending on the feature status
await ConfigureMainMenuAsync(context);
}
However, when doing the same check on a background worker, sometimes we get a different result:
protected override async Task DoWorkAsync(PeriodicBackgroundWorkerContext workerContext)
{
await Parallel.ForEachAsync(await TenantStore.GetListAsync(), tenantParallelOptions, async (tenant, ct) =>
{
try
{
using (CurrentTenant.Change(tenant.Id))
{
if (!await featureChecker.IsEnabledAsync(MyDefinitionProvider.MyFeature))
return;
// some logic here that should only execute when the feature is enabled
// this is where we get the inconsistency, since even with the feature enabled and menu visible, sometimes this is not executed
}
}
catch (Exception ex)
{
Logger.LogError(ex, "Error for tenant {TenantId}", tenant.Id);
}
});
}
This is a bit convoluted to reproduce, but from what we could gather it has something to do with enabling/disabling the feature for the tenant or edition, and the edition being assigned/unassigned from the tenant.
This can result in the scenario below where the row that holds the tenant status for the feature is simply deleted from the table. And THIS is when we observe the inconsistency stated above.
I know it's a little confusing, but if necessary we can schedule a call to explain in detail.
Using the module entity extension system, I'm adding a few custom properties to the Plan entity from the Payment Module. That works as expected except for one of the properties, where I need the field in the UI to allow multiple lines (text area), but instead in the UI the field is still rendered as a simple single line text input, not allowing me to input what I need.
According to the documentation:
DataTypeAttribute
is used to specify the type of the property. It is used to determine how to render the property on the user interface
So, my understanding was that by setting the data type of my property to DataType.MultilineText
as shown below, it should result in a text area field where I can type multiple lines of text, but that is not the case. Am I missing something?
Here's my custom property definition:
ObjectExtensionManager.Instance.Modules()
.ConfigurePayment(payment =>
{
payment.ConfigurePlan(plan => plan
.AddOrUpdateProperty<string>("Features", property =>
{
property.DisplayName = LocalizableString.Create<PaymentGatewayResource>("PlanFeatures");
property.Attributes.Add(new DataTypeAttribute(DataType.MultilineText));
property.UI.OnTable.IsVisible = false;
})
);
});