# Copyright (c) 2010 Flowerfire, Inc. All Rights Reserved.
autodesk_network_license_manager = {
plugin_version = "1.3.2"
info.1.manufacturer = "Autodesk"
info.1.device = "Network License Manager (FlexLM)"
info.1.version = ""
# 2008-05-05 - 1.0 - KBB - Initial creation. This plug-in uses data from three log files.
# One is primary and the other two provide additional data that will be used until the
# file is encountered again and it changes. This data is saved in the node (file) autodesk.cfg.
# 2008-05-29 - 1.0.1 - KBB - Improved autodetect after receiving sample without options file line.
# 2008-06-21 - 1.2 - KBB - Corrected problem with negative duration and missing dates caused by
# some TIMESTAMPs being skipped because the first characer was space instead of 0. Changed the
# saving of start times from collected fields to nodes so that they can be used when the
# database is updated.
# 2008-06-23 - 1.3 - KBB - Changed collection of license information to allow multiple licenses,
# which are matched to the events by the product ID. Other changes to accomodate more complex license
# files. Created custom report with all product information in separate columns. Added product_name to
# key for saving start times. Added constant for number of allowed license files. Error is printed
# if number is exceeded.
# 2008-06-30 - 1.3.1 - KBB - Added support for a format variation in the license file and lowercased
# product name for nodes in case it is different between logs and license file.
# 2008-08-11 - 1.3.2 - KBB - Added mapping for value of action field to allow translation.
# The name of the log format
log.format.format_label = "Autodesk Network License Manager (FlexLM) Log Format"
log.miscellaneous.log_data_type = "generic"
log.miscellaneous.log_format_type = "other"
# The log is in this format if any of the first ten lines match this regular expression
##DeptpName #ComputerName #UserName #IP_Address
#VENDOR adskflex option="C:\Program Files\Autodesk Network License Manager\License\adskflex.opt" port=2080
#13:34:14 (adskflex) Using options file: "C:\Program Files\Autodesk Network License Manager\License\adskflex.opt"
#13:34:10 (lmgrd) License file(s): C:\AutoDesk\123-45678901(1).lic
#16:56:31 (lmgrd) License file(s): C:\Program Files\Autodesk Network License Manager\License\123-45678901(9).lic
log.format.autodetect_expression = `
matches_regular_expression(volatile.log_data_line, '^\\#DeptpName \\#ComputerName \\#UserName \\#IP_Address$') or
matches_regular_expression(volatile.log_data_line, '^VENDOR [^ ]+ option="[^"]+" port=[0-9]+$') or
matches_regular_expression(volatile.log_data_line, '^[0-9]{2}:[0-9]{2}:[0-9]{2} \\([^)]+\\) Using options file: "[^"]+"$') or
matches_regular_expression(volatile.log_data_line, '^[0-9]{2}:[0-9]{2}:[0-9]{2} \\([^)]+\\) License file\\(s\\): ')
`
log.format.autodetect_lines = 100;
# The format of dates and times in this log
log.format.date_format = "m/d/yyyy"
log.format.time_format = "auto"
# All log field parsing will be done using the parsing filters
log.format.parse_only_with_filters = "true"
# Log fields
log.fields = {
date = ""
time = ""
# from debug file
user = ""
action = ""
reason = ""
duration = "" # calculated
# from dept file
department = ""
#computer = ""
#username = ""
ip_address = ""
# from license file
license_server_name = ""
license_server_mac_address = ""
product_name = ""
maximum_concurrent_users = ""
license_activation_date = ""
product_serial_number = ""
} # log.fields
log.filter_initialization = `
int license_file_limit = 3;
autodesk.timestamp = epoc_to_date_time(now());
node autodesk = 'autodesk.timestamp';
v.date = '';
v.first_time = 0;
v.product_name = '';
`
# Log Parsing Filters
log.parsing_filters.parse = `
v.line = current_log_line();
# This needs to be done with nodes because already processed, unchanged
# license files will not be seen during a database update.
v.path = current_log_pathname();
if (ends_with(v.path, '.lic')) then (
v.path = replace_all(v.path, '.', '_dot_');
int license_file_count = 1;
if (!subnode_exists('autodesk', 'license_files')) then (
set_subnode_value('autodesk', 'license_files', "");
);
if (subnode_exists('autodesk.license_files', v.path)) then (
# Failing here would indicate that autodesk.cfg had been edited or the limit had been decreased.
if (num_subnodes('autodesk.license_files') > license_file_limit) then (
save_node('autodesk');
error(lang_admin.messages.too_many_license_files_error . '
' . lang_admin.messages.allowed_license_files_message . license_file_limit);
);
);
else (
if (num_subnodes('autodesk.license_files') < license_file_limit) then (
set_subnode_value('autodesk.license_files', v.path, "");
);
# This is the more normal failure; an extra license file has been encountered.
else (
save_node('autodesk');
error(lang_admin.messages.too_many_license_files_error . '
' . lang_admin.messages.allowed_license_files_message . license_file_limit);
);
);
);
##DeptpName #ComputerName #UserName #IP_Address
#Design Verthandi Administrator 192.168.3.33
#Design Gethen Estraven 192.168.3.34
#Structure Urth Severian 192.168.3.53
#Structure Urth Jonas 192.168.3.53
if (matches_regular_expression(v.line, '^([^ ]+) ([^ ]+) ([^ ]+) ([0-9.]+)$')) then (
v.user = lowercase($3 . '@' . $2);
set_subnode_value('autodesk', v.user, "");
set_subnode_value('autodesk.' . v.user, 'department', $1);
set_subnode_value('autodesk.' . v.user, 'ip_address', $4);
); # department file
#SERVER earthsea 0040250D5207
#USE_SERVER
#VENDOR adskflex option="C:\Program Files\Autodesk Network License Manager\License\adskflex.opt" port=2080
#PACKAGE 64300ACD_F adskflex 1.000 COMPONENTS="57600ACD_2009_0F \
# 54600ACD_2008_0F 51200ACD_2007_0F 48800ACD_2006_0F" \
# OPTIONS=SUITE SUPERSEDE ISSUED=25-Apr-2008 SIGN="0C3D 8644 \
# E012 3B07 8548 004B 0454 C3C7 CD0C C49E AFB0 5DEB 39AA AD4A \
# E123 0AFF EB90 0A37 E96D AB1F 7CD4 388B 3EBF 3318 6748 949C \
# B867 D272 7909 DCED" SIGN2="0667 0D99 87E8 4184 BE69 5933 06F9 \
# A915 D005 363C 05DA C2DD C465 857F 9982 0BBC 86D5 D7D5 3DB9 \
# E0C9 3501 5911 2B6D E827 6B4E 8766 F4CE 3539 3CCB FFAC"
#INCREMENT 64300ACD_F adskflex 1.000 15-jun-2008 1 \
# VENDOR_STRING=nfr:extendable BORROW=4320 SUPERSEDE \
# DUP_GROUP=UH ISSUED=15-Apr-2008 SN=354-94060732 SIGN="1CC5 \
# 3A89 D40F EF00 8355 BA61 A4C7 238A 0232 F6CC 487E 423F F0EC \
# Variant without date:
#INCREMENT 54900AMECH_PP_2008_0F adskflex 1.000 permanent 9 \
else if (matches_regular_expression(v.line, '^SERVER ([^ ]+) ([0-9A-Da-d]{12})$')) then (
set_subnode_value('autodesk', 'license_server_name', $1);
set_subnode_value('autodesk', 'license_server_mac_address', $2);
);
else if (matches_regular_expression(v.line, '^INCREMENT ([^ ]+) [^ ]+ [0-9.]+ [^ ]+ ([0-9]+) \\\\\\\\\$')) then (
v.product_name = lowercase($1);
set_subnode_value('autodesk', v.product_name, "");
set_subnode_value('autodesk.' . v.product_name, 'maximum_concurrent_users', $2);
);
else if (matches_regular_expression(v.line, '^PACKAGE [^ ]+ [^ ]+ [0-9.]+ COMPONENTS=')) then (
# Clear the product name to avoid changing the date for
# the previous product when ISSUED is encountered.
v.product_name = "";
);
# The product name should have been seen by now, but skip this if it hasn't,
# or if PACKAGE has been seen since.
# These are usually on the same line, but not always.
else if (matches_regular_expression(v.line, '[ ](SN=|ISSUED=)') and
(v.product_name ne '') and subnode_exists('autodesk', v.product_name)) then (
if (matches_regular_expression(v.line, 'SN=([^ ]+) ?')) then (
set_subnode_value('autodesk.' . v.product_name, 'product_serial_number', $1);
);
if (matches_regular_expression(v.line, 'ISSUED=([^ ]+) ?')) then (
set_subnode_value('autodesk.' . v.product_name, 'license_activation_date', $1);
);
);
#13:34:10 (lmgrd) FLEXnet Licensing (v11.4.0.0 build 31341) started on gits-kenny (IBM PC) (4/28/2008)
#13:34:16 (lmgrd) TIMESTAMP 4/30/2008
else if (matches_regular_expression(v.line, '^[0-9 ][0-9]:[0-9]{2}:[0-9]{2} \\\\([^)]*\\\\) FLEXnet Licensing \\\\([^)]*\\\\) started on [^ ]+ \\\\([^)]+\\\\) \\\\(([0-9]{1,2}/[0-9]{1,2}/[0-9]{4})\\\\)$') or
matches_regular_expression(v.line, '^[0-9 ][0-9]:[0-9]{2}:[0-9]{2} \\\\([^)]*\\\\) TIMESTAMP ([0-9]{1,2}/[0-9]{1,2}/[0-9]{4})$')) then (
v.date = $1;
);
#15:03:13 (adskflex) OUT: "54600ACD_2008_0F" Administrator@earthsea
#15:03:42 (adskflex) DENIED: "54600ACD_2008_0F" Administrator@urth (Licensed number of users already reached. (-4,342))
#15:03:42 (adskflex) DENIED: "54600ACD_2008_0F" Administrator@urth (Licensed number of users already reached. (-4,342))
#15:04:01 (adskflex) DENIED: "54600ACD_2008_0F" Administrator@urth (Licensed number of users already reached. (-4,342))
#15:04:01 (adskflex) DENIED: "54600ACD_2008_0F" Administrator@urth (Licensed number of users already reached. (-4,342))
#15:06:20 (adskflex) IN: "54600ACD_2008_0F" Administrator@earthsea
#15:06:21 (adskflex) OUT: "54600ACD_2008_0F" Administrator@urth
#15:08:11 (adskflex) DENIED: "54600ACD_2008_0F" Administrator@earthsea (Licensed number of users already reached. (-4,342))
#15:08:11 (adskflex) DENIED: "54600ACD_2008_0F" Administrator@earthsea (Licensed number of users already reached. (-4,342))
#15:09:51 (adskflex) IN: "54600ACD_2008_0F" Administrator@urth
else if (matches_regular_expression(v.line, '^ ?([0-9]{1,2}:[0-9]{2}:[0-9]{2}) \\\\([^)]+\\\\) ([A-Z]+): "([^"]+)" (([^ ]+)@([^ ]+)) *(\\\\((.*)\\\\))?$')) then (
v.action = $2;
v.product_name = lowercase($3);
v.user = lowercase($4); # for access to node and key below
set_collected_field('', 'time', $1);
set_collected_field('', 'date', v.date);
#set_collected_field('', 'action', v.action);
set_collected_field('', 'product_name', $3);
set_collected_field('', 'user', $4);
set_collected_field('', 'reason', $8);
if (node_exists('lang_stats.log_formats.autodesk_network_license_manager.action.' . v.action)) then (
set_collected_field('', 'action', node_value('lang_stats.log_formats.autodesk_network_license_manager.action.' . v.action));
);
else (
set_collected_field('', 'action', v.action);
);
if (v.first_time == 0) then (
v.first_time = date_time_to_epoc(get_collected_field('', 'date_time'));
);
if (subnode_exists('autodesk', v.user)) then (
#set_collected_field('', 'computer', v.computer);
#set_collected_field('', 'username', node_value('autodesk.' . v.computer . '.username'));
set_collected_field('', 'ip_address', node_value('autodesk.' . v.user . '.ip_address'));
set_collected_field('', 'department', node_value('autodesk.' . v.user . '.department'));
);
if (subnode_exists('autodesk', 'license_server_name')) then (
set_collected_field('', 'license_server_name', node_value('autodesk.license_server_name'));
);
if (subnode_exists('autodesk', 'license_server_mac_address')) then (
set_collected_field('', 'license_server_mac_address', node_value('autodesk.license_server_mac_address'));
);
int max_users = 0;
if (subnode_exists('autodesk', v.product_name)) then (
if (subnode_exists('autodesk.' . v.product_name, 'license_activation_date')) then (
set_collected_field('', 'license_activation_date', node_value('autodesk.' . v.product_name . '.license_activation_date'));
);
if (subnode_exists('autodesk.' . v.product_name, 'product_serial_number')) then (
set_collected_field('', 'product_serial_number', node_value('autodesk.' . v.product_name . '.product_serial_number'));
);
if (subnode_exists('autodesk.' . v.product_name, 'maximum_concurrent_users')) then (
max_users = node_value('autodesk.' . v.product_name . '.maximum_concurrent_users'); # used below
set_collected_field('', 'maximum_concurrent_users', max_users);
);
);
# Calculate duration.
#
# There is no true key, so overlapping IN/OUT events for the same user will be
# assumed to end in the same order they started.
#
# Action OUT means take a license out of the license pool, so it is the START.
# Action IN means restore a license to the license pool, so it is the END.
# Save the start time if this is an OUT event.
v.base_key = v.user . '_' . v.product_name . '_';
if (v.action eq 'OUT') then (
int i = 0;
v.key = v.base_key . i;
# Note that keys are separate from users so that it isn't necessary to check
# for two nodes and in case the user was not in the Department file.
while (subnode_exists('autodesk', v.key)) (
i++;
v.key = v.base_key . i;
);
set_subnode_value('autodesk', v.key, date_time_to_epoc(get_collected_field('', 'date_time')));
); # OUT
# Calculate the duration if this is an IN event and we have a start time for the OUT event.
else if (v.action eq 'IN') then (
int start_time = 0;
int i = 0;
v.key = v.base_key . i;
while (subnode_exists('autodesk', v.key)) (
start_time = node_value('autodesk.' . v.key);
i++;
v.key = v.base_key . i;
);
if (start_time == 0) then (
start_time = v.first_time; # Use the beginning of the log
);
if (start_time > 0) then (
i--;
v.key = v.base_key . i;
int end_time = date_time_to_epoc(get_collected_field('', 'date_time'));
set_collected_field('', 'duration', 0.0 + (end_time - start_time));
if (subnode_exists('autodesk', v.key)) then (
delete_node('autodesk.' . v.key); # clear start_time
);
);
); # IN
accept_collected_entry('', false);
);
`
log.filter_finalization = `save_node('autodesk');`
# Database fields
database.fields = {
date_time = ""
hour_of_day = ""
day_of_week = ""
# from debug file
user = "" # username@computer
action = ""
reason = ""
# from dept file
department = ""
#computer = ""
#username = ""
ip_address = ""
# from license file
license_server_name = ""
license_server_mac_address = ""
product_name = ""
maximum_concurrent_users = ""
license_activation_date = ""
product_serial_number = ""
} # database.fields
# Log Filters
log.filters = {
mark_entry = {
label = '$lang_admin.log_filters.mark_entry_label'
comment = '$lang_admin.log_filters.mark_entry_comment'
value = 'events = 1;'
} # mark_entry
} # log.filters
database.numerical_fields = {
events = {
default = true
requires_log_field = false
entries_field = true
} # events
duration = {
default = true
type = float
display_format_type = duration_compact
} # duration
} # database.numerical_fields
create_profile_wizard_options = {
# Specify the reports menu manually
manual_reports_menu = true
# How the reports should be grouped in the report menu
report_groups = {
overview.type = "overview"
date_time_group = {
items = {
date_time = {
label = "$lang_stats.miscellaneous.years_months_days"
only_bottom_level_items = false
}
days = {
label = "$lang_stats.miscellaneous.days"
database_field_name = "date_time"
}
day_of_week = ""
hour_of_day = ""
}
} # date_time_group
users_group = {
items = {
user = ""
department = ""
ip_address = ""
}
}
actions_group = {
items = {
action = ""
reason = ""
}
}
product_information_group = {
items = {
product_information = {
label = "{=capitalize(pluralize(print(lang_stats.field_labels.product_information)))=}"
columns = {
0.field_name = "product_name"
1.field_name = "maximum_concurrent_users"
2.field_name = "license_activation_date"
3.field_name = "product_serial_number"
4.field_name = "events"
5.field_name = "duration"
} # columns
} # product_information
product_name = ""
maximum_concurrent_users = ""
license_activation_date = ""
product_serial_number = ""
}
}
server_group = {
items = {
license_server_name = ""
license_server_mac_address = ""
}
}
log_detail = true
single_page_summary = true
} # report_groups
} # create_profile_wizard_options
} # autodesk_network_license_manager