diff --git a/docs/sources/vendor/Citrix/netscaler.md b/docs/sources/vendor/Citrix/netscaler.md
index a758992eff..1f14a51d9a 100644
--- a/docs/sources/vendor/Citrix/netscaler.md
+++ b/docs/sources/vendor/Citrix/netscaler.md
@@ -7,27 +7,33 @@
## Links
-| Ref | Link |
-|----------------|---------------------------------------------------------------------------------------------------------|
-| Splunk Add-on | |
+| Ref | Link |
+|----------------|-----------------------------------------------------------------------------------------------------|
+| Splunk Add-on | |
| Product Manual | |
## Sourcetypes
-| sourcetype | notes |
-|----------------|---------------------------------------------------------------------------------------------------------|
-| citrix:netscaler:syslog | None |
-| citrix:netscaler:appfw | None |
-| citrix:netscaler:appfw:cef | None |
+| sourcetype | notes |
+|----------------------------|-------|
+| citrix:netscaler:syslog | None |
+| citrix:netscaler:appfw | None |
+| citrix:netscaler:appfw:cef | None |
## Sourcetype and Index Configuration
-| key | sourcetype | index | notes |
-|----------------|----------------|----------------|----------------|
-| citrix_netscaler | citrix:netscaler:syslog | netfw | none |
-| citrix_netscaler | citrix:netscaler:appfw | netfw | none |
-| citrix_netscaler | citrix:netscaler:appfw:cef | netfw | none |
+| key | sourcetype | index | notes |
+|------------------|----------------------------|-------|-------|
+| citrix_netscaler | citrix:netscaler:syslog | netfw | none |
+| citrix_netscaler | citrix:netscaler:appfw | netfw | none |
+| citrix_netscaler | citrix:netscaler:appfw:cef | netfw | none |
## Source Setup and Configuration
-* Follow vendor configuration steps per Product Manual above. Ensure the data format selected is "DDMMYYYY"
+* Follow vendor configuration steps per Product Manual above.
+
+## Options
+
+| Variable | default | description |
+|--------------------------------------------|--------------|-----------------------------------------------------------------------------------------------|
+| `SC4S_IGNORE_MMDD_LEGACY_CITRIX_NETSCALER` | empty string | (empty/yes) Set to "yes" for parsing the date in format `dd/mm/yyyy` instead of `mm/dd/yyyy`. |
diff --git a/package/enterprise/etc/conf.d/conflib/almost-syslog/app-almost-syslog-citrix_netscaler.conf b/package/enterprise/etc/conf.d/conflib/almost-syslog/app-almost-syslog-citrix_netscaler.conf
index 0408a0ff77..a5316cc179 100644
--- a/package/enterprise/etc/conf.d/conflib/almost-syslog/app-almost-syslog-citrix_netscaler.conf
+++ b/package/enterprise/etc/conf.d/conflib/almost-syslog/app-almost-syslog-citrix_netscaler.conf
@@ -10,7 +10,7 @@ block parser app-almost-syslog-citrix_netscaler() {
parser {
regexp-parser(
prefix(".tmp.")
- patterns('^(?\<\d+>) (?(?\d\d)\/\d\d\/\d\d\d\d:\d\d:\d\d:\d\d ?(?\w+))? (?[^ ]+) (?[A-Z\-0-9]+ : .*)')
+ patterns('^(?\<\d+\>) (?(?\d\d)\/\d\d\/\d\d\d\d:\d\d:\d\d:\d\d ?(?\w+))? (?[^ ]+) (?[A-Z\-0-9]+ : .*)')
);
};
parser {
@@ -19,11 +19,12 @@ block parser app-almost-syslog-citrix_netscaler() {
);
};
+
if {
- filter { "${.tmp.tspart1}" eq "$R_DAY"};
+ filter { "`SC4S_IGNORE_MMDD_LEGACY_CITRIX_NETSCALER`" eq "yes" or "${.tmp.tspart1}" eq "${DAY}"};
parser {
date-parser-nofilter(
- format('%d/%m/%Y:%H:%M:%S %z','%d/%m/%Y:%H:%M:%S')
+ format('%d/%m/%Y:%H:%M:%S %z','%d/%m/%Y:%H:%M:%S','%d/%m/%Y:%H:%M:%S %Z')
template("${.tmp.timestamp}")
);
};
diff --git a/package/etc/conf.d/conflib/almost-syslog/app-almost-syslog-citrix_netscaler.conf b/package/etc/conf.d/conflib/almost-syslog/app-almost-syslog-citrix_netscaler.conf
index 0408a0ff77..a5316cc179 100644
--- a/package/etc/conf.d/conflib/almost-syslog/app-almost-syslog-citrix_netscaler.conf
+++ b/package/etc/conf.d/conflib/almost-syslog/app-almost-syslog-citrix_netscaler.conf
@@ -10,7 +10,7 @@ block parser app-almost-syslog-citrix_netscaler() {
parser {
regexp-parser(
prefix(".tmp.")
- patterns('^(?\<\d+>) (?(?\d\d)\/\d\d\/\d\d\d\d:\d\d:\d\d:\d\d ?(?\w+))? (?[^ ]+) (?[A-Z\-0-9]+ : .*)')
+ patterns('^(?\<\d+\>) (?(?\d\d)\/\d\d\/\d\d\d\d:\d\d:\d\d:\d\d ?(?\w+))? (?[^ ]+) (?[A-Z\-0-9]+ : .*)')
);
};
parser {
@@ -19,11 +19,12 @@ block parser app-almost-syslog-citrix_netscaler() {
);
};
+
if {
- filter { "${.tmp.tspart1}" eq "$R_DAY"};
+ filter { "`SC4S_IGNORE_MMDD_LEGACY_CITRIX_NETSCALER`" eq "yes" or "${.tmp.tspart1}" eq "${DAY}"};
parser {
date-parser-nofilter(
- format('%d/%m/%Y:%H:%M:%S %z','%d/%m/%Y:%H:%M:%S')
+ format('%d/%m/%Y:%H:%M:%S %z','%d/%m/%Y:%H:%M:%S','%d/%m/%Y:%H:%M:%S %Z')
template("${.tmp.timestamp}")
);
};
diff --git a/package/lite/etc/addons/citrix/app-almost-syslog-citrix_netscaler.conf b/package/lite/etc/addons/citrix/app-almost-syslog-citrix_netscaler.conf
index 0408a0ff77..a5316cc179 100644
--- a/package/lite/etc/addons/citrix/app-almost-syslog-citrix_netscaler.conf
+++ b/package/lite/etc/addons/citrix/app-almost-syslog-citrix_netscaler.conf
@@ -10,7 +10,7 @@ block parser app-almost-syslog-citrix_netscaler() {
parser {
regexp-parser(
prefix(".tmp.")
- patterns('^(?\<\d+>) (?(?\d\d)\/\d\d\/\d\d\d\d:\d\d:\d\d:\d\d ?(?\w+))? (?[^ ]+) (?[A-Z\-0-9]+ : .*)')
+ patterns('^(?\<\d+\>) (?(?\d\d)\/\d\d\/\d\d\d\d:\d\d:\d\d:\d\d ?(?\w+))? (?[^ ]+) (?[A-Z\-0-9]+ : .*)')
);
};
parser {
@@ -19,11 +19,12 @@ block parser app-almost-syslog-citrix_netscaler() {
);
};
+
if {
- filter { "${.tmp.tspart1}" eq "$R_DAY"};
+ filter { "`SC4S_IGNORE_MMDD_LEGACY_CITRIX_NETSCALER`" eq "yes" or "${.tmp.tspart1}" eq "${DAY}"};
parser {
date-parser-nofilter(
- format('%d/%m/%Y:%H:%M:%S %z','%d/%m/%Y:%H:%M:%S')
+ format('%d/%m/%Y:%H:%M:%S %z','%d/%m/%Y:%H:%M:%S','%d/%m/%Y:%H:%M:%S %Z')
template("${.tmp.timestamp}")
);
};
diff --git a/tests/test_citrix_netscaler.py b/tests/test_citrix_netscaler.py
index b7e6413298..ef6f661c6d 100644
--- a/tests/test_citrix_netscaler.py
+++ b/tests/test_citrix_netscaler.py
@@ -4,6 +4,9 @@
# license that can be found in the LICENSE-BSD2 file or at
# https://opensource.org/licenses/BSD-2-Clause
import datetime
+import os
+from unittest.mock import patch
+
import shortuuid
import pytz
import pytest
@@ -28,7 +31,7 @@ def test_citrix_netscaler(record_property, setup_splunk, setup_sc4s, get_pid):
_, bsd, time, _, _, tzname, epoch = time_operations(dt)
# Tune time functions
- time = dt.strftime("%d/%m/%Y:%H:%M:%S")
+ time = dt.strftime("%m/%d/%Y:%H:%M:%S")
epoch = epoch[:-7]
mt = env.from_string(
@@ -91,6 +94,49 @@ def test_citrix_netscaler_sdx(
assert result_count == 1
+# <134> 05/08/2025:03:13:15 GMT DC-NS02 0-PPE-0 : default TCP CONN_TERMINATE 1874124822 0 : Source 10.x.x.x:47990 - Destination 10.x.x.x:80 - Start Time 26/03/2025:21:13:15 GMT - End Time 26/03/2025:21:13:15 GMT - Total_bytes_send 1 - Total_bytes_recv 1
+@pytest.mark.addons("citrix")
+@patch.dict(
+ os.environ,
+ {
+ "SC4S_IGNORE_MMDD_LEGACY_CITRIX_NETSCALER": "yes",
+ },
+ clear=False
+)
+def test_citrix_netscaler_new_date_format(
+ record_property, setup_splunk, setup_sc4s, get_pid
+):
+ host = f"test-ctitrixns-host-{shortuuid.ShortUUID().random(length=5).lower()}-{shortuuid.ShortUUID().random(length=5).lower()}"
+ pid = get_pid
+
+ dt = datetime.datetime.now(datetime.timezone.utc)
+ _, bsd, time, _, _, tzname, epoch = time_operations(dt)
+
+ # Tune time functions
+ time = dt.strftime("%d/%m/%Y:%H:%M:%S")
+ epoch = epoch[:-7]
+
+ mt = env.from_string(
+ "{{ mark }} {{ time }} GMT {{ host }} 0-PPE-0 : default TCP CONN_TERMINATE 1874124822 0 : Source 10.x.x.x:47990 - Destination 10.x.x.x:80 - Start Time 26/03/2025:21:13:15 GMT - End Time 26/03/2025:21:13:15 GMT - Total_bytes_send 1 - Total_bytes_recv 1\n"
+ )
+ message = mt.render(
+ mark="<134>", bsd=bsd, time=time, tzname=tzname, host=host, pid=pid
+ )
+
+ sendsingle(message, setup_sc4s[0], setup_sc4s[1][514])
+
+ st = env.from_string(
+ 'search _time={{ epoch }} index=netfw host={{ host }} sourcetype="citrix:netscaler:syslog"'
+ )
+ search = st.render(epoch=epoch, host=host, pid=pid)
+
+ result_count, _ = splunk_single(setup_splunk, search)
+
+ record_property("host", host)
+ record_property("resultCount", result_count)
+ record_property("message", message)
+
+ assert result_count == 1
# [289]: AAA Message : In receive_ldap_user_search_event: ldap_first_entry returned null, user ssgconfig not found
@pytest.mark.addons("citrix")