Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Application usage statistics - #2387

Merged
chrisknoll merged 15 commits into
masterfrom
application-usage-statistics
Mar 18, 2025
Merged

Application usage statistics#2387
chrisknoll merged 15 commits into
masterfrom
application-usage-statistics

Conversation

@alex-odysseus

@alex-odysseus alex-odysseus commented Aug 27, 2024

Copy link
Copy Markdown
Contributor

Addressing #2329

Business logic is based on parsing Audit Trail log entries. As some of the Analysis Execution entries were identified as duplicates a filter has been introduced to count each Analysis Execution precisely once

Usage examples (for the second one {} is used in the 'urlPattern' parameter to indicated a dynamic part of the URL):

curl --location --request POST 'localhost:8080/WebAPI/statistic/executions' \
--header 'Content-Type: application/json' \
--header 'Cookie: JSESSIONID=398******************EB0' \
--data-raw '{
"startDate":"2023-11-01",
"endDate":"2023-11-10",
"sourceKey":"SYNPUF_110k"
}'

curl --location --request POST 'localhost:8080/WebAPI/statistic/accesstrends' \
--header 'Content-Type: application/json' \
--header 'Cookie: JSESSIONID=398************************EB0' \
--data-raw '{
"startDate":"2024-03-12",
"endDate":"2024-03-12",
"endpoints":[{"method":"POST","urlPattern":"/WebAPI/conceptset/check"},{"method":"GET","urlPattern":"/WebAPI/i18n/locales"},{"method":"GET","urlPattern":"/WebAPI/cdmresults/{}/dashboard"}],
"responseFormat":"CSV",
"showUserInformation":true
}'


@Controller
@Path("/statistic/")
@ConditionalOnProperty(value = "audit.trail.enabled", havingValue = "true")

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If Audit Trail feature is not enabled the Controller is not efficient

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the intent here to make the /statistic/ end-point available based on the audit.trail.enabled property? Seems a little confusing to make an endpoint conditional vs. having it always available and to have it return based on the status of the configuration of the application.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I personally see no problem that some of the endpoints are not available if an appropriate configuration is not at place

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with @anthonysena, it is confusing because people will look at api docs and think they can call an endpoint, but it won't exist, which is confusing.

I don't see any documentation that describes that this end-piont doesn't exist when the configuration is not set.

We have rules about opt-in flags for default behavior (such as logging should be turned on/off, or auditing is enabled/distables) but the invocation of a end-point is the opt-in request of the user. If it's not enabled, it would be better to raise an error message saying 'auditing is not enabled' then return a 404 that a conditional-endpoint does not exist.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed as suggested

private StatisticService service;

public enum ResponseFormat {
CSV, JSON

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both CSV and JSON output formats should be supported

}
}

private void updateExecutionStatisticsHeader(boolean showUserInformation) {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both methods to be replaced by extra two static constants!

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When will this be replaced?

private String sourceName;
private String executionName;
private String executionDate;
private String userID;

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

userId

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When do you plan to change this?

protected final Logger LOG = LoggerFactory.getLogger(getClass());

@Value("${audit.trail.log.file}")
// TODO remove value

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To be configured via properties

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So will you remove this then?

@@ -0,0 +1,2 @@
UPDATE ${ohdsiSchema}.sec_permission SET value='statistic:executions:post'

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We may combine both scripts into one

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, please do and make sure the prefix of the file is v2.15...

@anthonysena anthonysena linked an issue Sep 3, 2024 that may be closed by this pull request

@Controller
@Path("/statistic/")
@ConditionalOnProperty(value = "audit.trail.enabled", havingValue = "true")

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the intent here to make the /statistic/ end-point available based on the audit.trail.enabled property? Seems a little confusing to make an endpoint conditional vs. having it always available and to have it return based on the status of the configuration of the application.

}
}

private void updateExecutionStatisticsHeader(boolean showUserInformation) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When will this be replaced?

private String sourceName;
private String executionName;
private String executionDate;
private String userID;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When do you plan to change this?

protected final Logger LOG = LoggerFactory.getLogger(getClass());

@Value("${audit.trail.log.file}")
// TODO remove value

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So will you remove this then?

@@ -0,0 +1,2 @@
UPDATE ${ohdsiSchema}.sec_permission SET value='statistic:executions:post'

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, please do and make sure the prefix of the file is v2.15...

@chrisknoll

Copy link
Copy Markdown
Collaborator

Docker build fails due to (presumably) a JDK 11 docker config. We discussed and possible least-friction solution is to check the stream syntax on regex Matcher in the stream API. Failing that, may need to find an ARM compatible JDK 8 for docker.

@oleg-odysseus
oleg-odysseus force-pushed the application-usage-statistics branch from 831e3e7 to 1a431c3 Compare February 27, 2025 18:52
@oleg-odysseus

Copy link
Copy Markdown
Contributor

fixed issue with an invalid method reference exception during docker build, rebased.

…with a 404 Not Found instead when the Audit Trail property is not switched on
@Consumes(MediaType.APPLICATION_JSON)
public Response accessStatistics(AccessTrendsStatisticsRequest accessTrendsStatisticsRequest) {
if (!auditTrailEnabled) {
throw new NotFoundException("Audit Trail functionality should be enabled (audit.trail.enabled) to serve this endpoint");

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NotFound results in a 404, correct? We said that it would be confusing if someone looked at an api and attempted to call an endpoint and it was not found. I think we mentioned raising an error, such that it could return an HTTP 500 or some other HTTP code that represents an error other than 'not found'?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I misread your passage, corrected to the internal server error

@chrisknoll
chrisknoll merged commit c256508 into master Mar 18, 2025
@chrisknoll
chrisknoll deleted the application-usage-statistics branch March 18, 2025 12:35
@pieterlukasse

pieterlukasse commented Apr 10, 2025

Copy link
Copy Markdown
Contributor

hi @alex-odysseus , @chrisknoll sorry for the late review comment here, but I just wanted to raise a flag here. If I understand these changes correctly, the audit.trail.enabled setting already existed before. The behavior of this config setting was that it would ensure things get logged to some local audit.log file. I can imagine many installations might have turned this ON. Now, with this PR, the behavior changes significantly, by opening up new endpoints. This will happen silently, and therefore I think it is a potential security issue. Instead, I think this new feature should be controlled by a new config option that is set to false by default. Can you please consider changing this?

@alex-odysseus

Copy link
Copy Markdown
Contributor Author

Pieter, newly added endpoints should be available for the administrators only by default @pieterlukasse

@pieterlukasse

pieterlukasse commented Apr 14, 2025

Copy link
Copy Markdown
Contributor

@alex-odysseus thanks for the clarification.
Still, I think the change might come as a surprise to some.
As an admin, I would not like endpoints (albeit admin ones) to be silently opened.
Having said that, I understand all work you are doing is still on a "dev-like" branch and 2.15 is not officially released yet, so maybe it is fine if this is just highlighted in the release notes.

@chrisknoll

Copy link
Copy Markdown
Collaborator

Thanks @pieterlukasse , it's an interesting perspective. From a WebAPI perspective, we introduce new endpoints quite a bit. Never as a result of a hotfix release (ie x.x.1 -> x.x.2) but minor releases which add new non-backwards-breaking features to the app will bring along new endpoints (usually a new feature is exposed as a new endpoint). The hint to the admins is that if they are installing a new version of WebAPI (minor or major version increment) they should expect new endpionts.

Now, have we been proactive about announcing which new endpoints exist? Other than the automatic REST documentation that is generated that gives all the service endpoints, I don't think we make a habbit of itemizing each new endpint in our release notes, we usually just declare the new feature, point it to the PR, and then if you want to know the technical details, it's there.

Could we do more than that? Possibly, given the resources. Should anyone be surprised about new endpoints in new releases? Probably not, that should almost be the expectation.

In this specific case, a couple endpoints were added to provide reporting on the audits that are enabled via config. So, the release notes will say something about exposing audit train reports, and pointing to the PR that implements.

@pieterlukasse

Copy link
Copy Markdown
Contributor

Thanks for clarifying @chrisknoll . It helps me understand better how you are dealing with this. If this is mentioned in the release notes and points to the PR, then this sounds like a reasonable approach to me. It could be useful to add a line to this PR description stating that an existing config setting is being reused/partially repurposed to do something new.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Application usage statistics

7 participants