Added logs admin viewer.

Added CMS_SETUP.is_debug: BOOLEAN  (see cms.ini   site.debug setting)
This commit is contained in:
2016-02-19 00:03:15 +01:00
parent af137629e0
commit 77e2c28d18
12 changed files with 274 additions and 21 deletions

View File

@@ -6,6 +6,7 @@ root-dir=site/www
[site] [site]
# General token that could be use for cookies, and related. # General token that could be use for cookies, and related.
id=_EIFFEL_CMS_ id=_EIFFEL_CMS_
#debug=true
# Name of the site, for the title, and eventual message. # Name of the site, for the title, and eventual message.
name=Eiffel CMS name=Eiffel CMS

View File

@@ -31,7 +31,7 @@ feature {NONE} -- Initialization
feature -- Access feature -- Access
id: INTEGER id: INTEGER_64
-- Unique identifier of Current. -- Unique identifier of Current.
category: READABLE_STRING_8 category: READABLE_STRING_8
@@ -124,4 +124,7 @@ feature -- Constants
level_info: INTEGER = 7 level_info: INTEGER = 7
level_debug: INTEGER = 8 level_debug: INTEGER = 8
note
copyright: "2011-2016, Javier Velilla, Jocelyn Fiat, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
end end

View File

@@ -54,6 +54,7 @@ feature -- Access: router
l_user_handler: CMS_USER_HANDLER l_user_handler: CMS_USER_HANDLER
l_role_handler: CMS_ROLE_HANDLER l_role_handler: CMS_ROLE_HANDLER
l_admin_logs_handler: CMS_LOGS_HANDLER
l_admin_cache_handler: CMS_ADMIN_CACHE_HANDLER l_admin_cache_handler: CMS_ADMIN_CACHE_HANDLER
l_admin_export_handler: CMS_ADMIN_EXPORT_HANDLER l_admin_export_handler: CMS_ADMIN_EXPORT_HANDLER
@@ -76,6 +77,11 @@ feature -- Access: router
create l_uri_mapping.make_trailing_slash_ignored ("/admin/roles", l_roles_handler) create l_uri_mapping.make_trailing_slash_ignored ("/admin/roles", l_roles_handler)
a_router.map (l_uri_mapping, a_router.methods_get_post) a_router.map (l_uri_mapping, a_router.methods_get_post)
create l_admin_logs_handler.make (a_api)
create l_uri_mapping.make_trailing_slash_ignored ("/admin/logs", l_admin_logs_handler)
a_router.map (l_uri_mapping, a_router.methods_get)
create l_admin_cache_handler.make (a_api) create l_admin_cache_handler.make (a_api)
create l_uri_mapping.make_trailing_slash_ignored ("/admin/cache", l_admin_cache_handler) create l_uri_mapping.make_trailing_slash_ignored ("/admin/cache", l_admin_cache_handler)
a_router.map (l_uri_mapping, a_router.methods_get_post) a_router.map (l_uri_mapping, a_router.methods_get_post)
@@ -108,6 +114,7 @@ feature -- Security
Result.force ("admin roles") Result.force ("admin roles")
Result.force ("admin modules") Result.force ("admin modules")
Result.force ("install modules") Result.force ("install modules")
Result.force ("view logs")
Result.force ("admin core caches") Result.force ("admin core caches")
Result.force ("clear blocks cache") Result.force ("clear blocks cache")
Result.force ("admin export") Result.force ("admin export")
@@ -148,18 +155,6 @@ feature -- Hooks
-- Per module export permission! -- Per module export permission!
create lnk.make ("Export", "admin/export") create lnk.make ("Export", "admin/export")
admin_lnk.extend (lnk) admin_lnk.extend (lnk)
-- if
-- a_response.has_permission ("access " + {CMS_ADMIN_MODULE}.name) -- Note: admin user has all permissions enabled by default.
-- then
-- lnk := admin_lnk
-- lnk.set_title ("Admin")
-- a_menu_system.management_menu.extend (lnk)
-- elseif admin_lnk.has_children then
-- a_menu_system.management_menu.extend (admin_lnk)
-- end
-- admin_lnk.set_permission_arguments (<<"access " + {CMS_ADMIN_MODULE}.name>>)
end end
end end

View File

@@ -26,6 +26,7 @@ feature -- Process
l_admin_links.force (["core", <<"admin users">>, local_link ("Users", "admin/users"), "View/Edit/Add Users"]) l_admin_links.force (["core", <<"admin users">>, local_link ("Users", "admin/users"), "View/Edit/Add Users"])
l_admin_links.force (["core", <<"admin roles">>, local_link ("Roles", "admin/roles"), "View/Edit/Add Roles"]) l_admin_links.force (["core", <<"admin roles">>, local_link ("Roles", "admin/roles"), "View/Edit/Add Roles"])
l_admin_links.force (["core", <<"admin modules">>, local_link ("Modules", "admin/modules"), "(un)Install modules"]) l_admin_links.force (["core", <<"admin modules">>, local_link ("Modules", "admin/modules"), "(un)Install modules"])
l_admin_links.force (["core", <<"view logs">>, local_link ("Logs", "admin/logs"), "View logs"])
l_admin_links.force (["support", <<"admin cache">>, local_link ("Cache", "admin/cache"), "Clear caches"]) l_admin_links.force (["support", <<"admin cache">>, local_link ("Cache", "admin/cache"), "Clear caches"])
l_admin_links.force (["support", <<"admin export">>, local_link ("Export", "admin/export"), "Export CMS contents, and modules contents."]) l_admin_links.force (["support", <<"admin export">>, local_link ("Export", "admin/export"), "Export CMS contents, and modules contents."])
create categories.make_caseless (3) create categories.make_caseless (3)

View File

@@ -0,0 +1,114 @@
note
description: "[
Handler for a CMS logs in the CMS interface.
]"
date: "$Date$"
revision: "$Revision$"
class
CMS_LOGS_HANDLER
inherit
CMS_HANDLER
WSF_URI_HANDLER
rename
execute as uri_execute,
new_mapping as new_uri_mapping
end
WSF_URI_TEMPLATE_HANDLER
rename
execute as uri_template_execute,
new_mapping as new_uri_template_mapping
select
new_uri_template_mapping
end
WSF_RESOURCE_HANDLER_HELPER
redefine
do_get
end
REFACTORING_HELPER
create
make
feature -- execute
execute (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Execute request handler
do
execute_methods (req, res)
end
uri_execute (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Execute request handler
do
execute (req, res)
end
uri_template_execute (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Execute request handler
do
execute (req, res)
end
feature -- HTTP Methods
do_get (req: WSF_REQUEST; res: WSF_RESPONSE)
-- <Precursor>
local
l_logs: LIST [CMS_LOG]
l_log: CMS_LOG
r: CMS_RESPONSE
l_cat: detachable READABLE_STRING_8
l_lower: INTEGER
l_count: INTEGER
b: STRING
do
if api.has_permission ("view logs") then
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api)
if attached {WSF_STRING} req.query_parameter ("category") as p_cat then
l_cat := p_cat.value
end
if attached {WSF_STRING} req.query_parameter ("lower") as p_lower and then p_lower.is_integer then
l_lower := p_lower.integer_value
end
if attached {WSF_STRING} req.query_parameter ("count") as p_count and then p_count.is_integer then
l_count := p_count.integer_value
end
l_logs := api.logs (l_cat, l_lower, l_count)
create b.make (100)
b.append ("<ul class=%"logs%">%N")
across
l_logs as ic
loop
l_log := ic.item
b.append ("<li class=%"log-level-"+ l_log.level.out +"%">")
b.append ("[" + l_log.category + "] ")
b.append (l_log.message)
b.append ("%N<p>(date: " + l_log.date.out + ")")
if attached l_log.link as lnk then
b.append (" <a href=%"" + req.script_url (lnk.location) + "%">" + html_encoded (lnk.title) + "</a>")
end
b.append ("</p>%N")
if attached l_log.info as l_info then
b.append ("<pre>" + l_info + "</pre>%N")
end
b.append ("</li>%N")
end
b.append ("</ul>%N")
r.set_main_content (b)
r.set_page_title ("Logs ...")
r.set_title ("Logs")
else
create {FORBIDDEN_ERROR_CMS_RESPONSE} r.make (req, res, api)
end
r.execute
end
end

View File

@@ -20,6 +20,9 @@ feature {NONE} -- Initialization
do do
site_location := environment.path site_location := environment.path
-- Debug mode.
is_debug := attached string_8_item ("site.debug") as l_debug and then l_debug.is_case_insensitive_equal_general ("yes")
--| Site id, used to identified a site, this could be set to a uuid, or else --| Site id, used to identified a site, this could be set to a uuid, or else
site_id := string_8_item_or_default ("site.id", "_ROC_CMS_NO_ID_") site_id := string_8_item_or_default ("site.id", "_ROC_CMS_NO_ID_")
@@ -259,6 +262,11 @@ feature -- Access: Site
-- Optional path defining the front page. -- Optional path defining the front page.
-- By default "" or "/". -- By default "" or "/".
feature -- Settings
is_debug: BOOLEAN
-- Is debug mode enabled?
feature -- Query feature -- Query
text_item (a_name: READABLE_STRING_GENERAL): detachable READABLE_STRING_32 text_item (a_name: READABLE_STRING_GENERAL): detachable READABLE_STRING_32

View File

@@ -93,6 +93,14 @@ feature -- Logs
do do
end end
logs (a_category: detachable READABLE_STRING_GENERAL; a_lower: INTEGER; a_count: INTEGER): LIST [CMS_LOG]
-- List of recent logs from `a_lower' to `a_lower+a_count'.
-- If `a_category' is set, filter to return only associated logs.
-- If `a_count' <= 0 then, return all logs.
do
create {ARRAYED_LIST [CMS_LOG]} Result.make (0)
end
feature -- Custom feature -- Custom
set_custom_value (a_name: READABLE_STRING_8; a_value: attached like custom_value; a_type: detachable READABLE_STRING_8) set_custom_value (a_name: READABLE_STRING_8; a_value: attached like custom_value; a_type: detachable READABLE_STRING_8)
@@ -128,6 +136,6 @@ feature -- Custom
end end
note note
copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Eiffel Software and others" copyright: "2011-2016, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
end end

View File

@@ -59,6 +59,13 @@ feature -- Logs
deferred deferred
end end
logs (a_category: detachable READABLE_STRING_GENERAL; a_lower: INTEGER; a_count: INTEGER): LIST [CMS_LOG]
-- List of recent logs from `a_lower' to `a_lower+a_count'.
-- If `a_category' is set, filter to return only associated logs.
-- If `a_count' <= 0 then, return all logs.
deferred
end
feature -- Misc feature -- Misc
set_custom_value (a_name: READABLE_STRING_8; a_value: attached like custom_value; a_type: detachable READABLE_STRING_8) set_custom_value (a_name: READABLE_STRING_8; a_value: attached like custom_value; a_type: detachable READABLE_STRING_8)
@@ -82,6 +89,6 @@ feature -- Misc
end end
note note
copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Eiffel Software and others" copyright: "2011-2016, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
end end

View File

@@ -206,9 +206,94 @@ feature -- Logs
sql_finalize sql_finalize
end end
logs (a_category: detachable READABLE_STRING_GENERAL; a_lower: INTEGER; a_count: INTEGER): ARRAYED_LIST [CMS_LOG]
-- <Precursor>.
local
l_parameters: detachable STRING_TABLE [detachable ANY]
l_sql: READABLE_STRING_8
do
error_handler.reset
create l_parameters.make (3)
if a_category /= Void then
l_parameters.put (a_category, "category")
l_sql := sql_select_categorized_logs
else
l_sql := sql_select_logs
end
if a_count > 0 then
l_parameters.put (a_lower, "offset")
l_parameters.put (a_count, "size")
check l_sql.ends_with_general (";") end
l_sql := l_sql.substring (1, l_sql.count - 1) -- Remove ';'
+ "LIMIT :size OFFSET :offset ;"
end
from
if a_count > 0 then
create Result.make (a_count)
else
create Result.make (10)
end
if l_parameters.is_empty then
l_parameters := Void
end
sql_query (l_sql, l_parameters)
sql_start
until
sql_after
loop
if attached fetch_log as l_log then
Result.force (l_log)
end
sql_forth
end
sql_finalize
end
fetch_log: detachable CMS_LOG
-- SQL: 1:id, 2:category, 3:level, 4:uid, 5:message, 6:info, 7:link, 8:date
local
l_cat: detachable READABLE_STRING_8
l_mesg: detachable READABLE_STRING_8
l_level: INTEGER
l_date: detachable DATE_TIME
i: INTEGER
lnk: CMS_LOCAL_LINK
do
l_cat := sql_read_string (2)
l_mesg := sql_read_string (5)
l_level := sql_read_integer_32 (3)
l_date := sql_read_date_time (8)
if l_cat = Void then
l_cat := "unknown"
end
if l_mesg = Void then
l_mesg := ""
end
create Result.make (l_cat, l_mesg, l_level, l_date)
Result.set_id (sql_read_integer_64 (1))
Result.set_info (sql_read_string (6))
if attached sql_read_string_32 (7) as l_link_text then
-- Format: "[title](location)"
i := l_link_text.index_of ('(', 1)
if i > 0 then
create lnk.make (l_link_text.substring (2, i - 2), l_link_text.substring (i + 1, l_link_text.count - 1))
Result.set_link (lnk)
end
end
end
sql_insert_log: STRING = "INSERT INTO logs (category, level, uid, message, info, link, date) VALUES (:category, :level, :uid, :message, :info, :link, :date);" sql_insert_log: STRING = "INSERT INTO logs (category, level, uid, message, info, link, date) VALUES (:category, :level, :uid, :message, :info, :link, :date);"
-- SQL Insert to add a new node. -- SQL Insert to add a new node.
sql_select_logs: STRING = "SELECT id, category, level, uid, message, info, link, date FROM logs ORDER by date DESC;"
-- SQL Insert to add a new node.
sql_select_categorized_logs: STRING = "SELECT id, category, level, uid, message, info, link, date FROM logs WHERE category=:category ORDER by date DESC;"
-- SQL Insert to add a new node.
feature -- Misc feature -- Misc
set_custom_value (a_name: READABLE_STRING_8; a_value: attached like custom_value; a_type: detachable READABLE_STRING_8) set_custom_value (a_name: READABLE_STRING_8; a_value: attached like custom_value; a_type: detachable READABLE_STRING_8)
@@ -326,6 +411,6 @@ feature -- Misc
note note
copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Eiffel Software and others" copyright: "2011-2016, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
end end

View File

@@ -170,6 +170,14 @@ feature -- Access
storage: CMS_STORAGE storage: CMS_STORAGE
-- Default persistence storage. -- Default persistence storage.
feature -- Settings
is_debug: BOOLEAN
-- Is debug mode enabled?
do
Result := setup.is_debug
end
feature {NONE} -- Access: request feature {NONE} -- Access: request
request: WSF_REQUEST request: WSF_REQUEST
@@ -261,6 +269,14 @@ feature -- Status Report
feature -- Logging feature -- Logging
logs (a_category: detachable READABLE_STRING_8; a_lower: INTEGER; a_count: INTEGER): LIST [CMS_LOG]
-- List of recent logs from `a_lower' to `a_lower+a_count'.
-- If `a_category' is set, filter to return only associated logs.
-- If `a_count' <= 0 then, return all logs.
do
Result := storage.logs (a_category, a_lower, a_count)
end
log (a_category: READABLE_STRING_8; a_message: READABLE_STRING_8; a_level: INTEGER; a_link: detachable CMS_LINK) log (a_category: READABLE_STRING_8; a_message: READABLE_STRING_8; a_level: INTEGER; a_link: detachable CMS_LINK)
local local
l_log: CMS_LOG l_log: CMS_LOG
@@ -674,11 +690,16 @@ feature -- Environment/ module
create {INI_CONFIG} Result.make_from_file (l_path) create {INI_CONFIG} Result.make_from_file (l_path)
end end
end end
if Result = Void and a_name /= Void then if Result = Void then
-- Use sub config from default? if
if attached {CONFIG_READER} module_configuration_by_name_in_location (a_module_name, a_dir, Void) as cfg then a_name /= Void and then
attached {CONFIG_READER} module_configuration_by_name_in_location (a_module_name, a_dir, Void) as cfg
then
-- Use sub config from default.
Result := cfg.sub_config (a_name) Result := cfg.sub_config (a_name)
end end
elseif Result.has_error then
log ("modules", "module configuration has error %"" + p.utf_8_name + "%"", {CMS_LOG}.level_error, Void)
end end
end end

View File

@@ -3,9 +3,12 @@ note
date: "$Date: 2015-02-13 14:54:27 +0100 (ven., 13 févr. 2015) $" date: "$Date: 2015-02-13 14:54:27 +0100 (ven., 13 févr. 2015) $"
revision: "$Revision: 96620 $" revision: "$Revision: 96620 $"
deferred class class
CMS_MODULE_API CMS_MODULE_API
create
make
feature {NONE} -- Initialization feature {NONE} -- Initialization
make (a_api: CMS_API) make (a_api: CMS_API)
@@ -67,6 +70,6 @@ feature -- Bridge to CMS API
end end
note note
copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Eiffel Software and others" copyright: "2011-2016, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
end end

View File

@@ -992,6 +992,13 @@ feature -- Message
m.append (a_msg + "</li>") m.append (a_msg + "</li>")
end end
add_debug_message (a_msg: READABLE_STRING_8)
do
if api.is_debug_enabled then
add_message (a_msg, "debug")
end
end
add_notice_message (a_msg: READABLE_STRING_8) add_notice_message (a_msg: READABLE_STRING_8)
do do
add_message (a_msg, "notice") add_message (a_msg, "notice")