Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Alfredops 715 fix ass 2.0.0 #74

Merged
merged 7 commits into from
Mar 22, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ Version template:
### Fixed

* Sharded solr monitoring throws exception in Alfresco 6.2
* Fixed and refactored code for solr, so that it works for ASS>=2.0.0. Improved handling of solrconfig.xml for solr6.

[#74] https://github.com/xenit-eu/alfred-telemetry/pull/74

## [0.4.0] - 2020-01-12

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,9 @@ dependencies {
implementation "io.github.mweirauch:micrometer-jvm-extras:0.1.2"
implementation "io.micrometer:micrometer-registry-graphite:1.6.1"

// compile against solr4 libraries
alfrescoProvided "org.alfresco:alfresco-solr4:5.2.g:classes@jar"
alfrescoProvided "org.alfresco:alfresco-solrclient:5.2.g"
alfrescoProvided ("org.apache.solr:solr-core:4.10.3") {
// compile against ASS 2.0.0 libraries
alfrescoProvided "org.alfresco:alfresco-search:2.0.0"
alfrescoProvided ("org.apache.solr:solr-core:6.6.5") {
exclude group: 'org.restlet.jee' // Only available in JCenter, not essential in this project.
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public class SolrTrackerMetrics implements MeterBinder {
AlfrescoCoreAdminHandler coreAdminHandler;
MeterRegistry registry;

Logger logger = LoggerFactory.getLogger(SolrMetrics.class);
Logger logger = LoggerFactory.getLogger(SolrTrackerMetrics.class);
Copy link
Contributor

Choose a reason for hiding this comment

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

Logger should be at least private, preferably also static final

  • private - so that no other class can hijack your logger
  • static - so there is only one logger instance per class, also avoiding attempts to serialize loggers
  • final - no need to change the logger over the lifetime of the class

https://stackoverflow.com/a/6653577


public SolrTrackerMetrics(AlfrescoCoreAdminHandler coreAdminHandler) {
this.coreAdminHandler = coreAdminHandler;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,13 @@ public static boolean isEnabled(String env) {

return (DEFAULT_DISABLED_CONFIGS.contains(env)?false:true);
}

public static boolean isVersionLowerThan2() {
try {
Class<?> cachedDocTransformerFactory = Class.forName("org.alfresco.solr.transformer.CachedDocTransformerFactory");
} catch (ClassNotFoundException e) {
return false;
}
return true;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package eu.xenit.alfred.telemetry.solr.monitoring.binder;

import eu.xenit.alfred.telemetry.solr.util.Util;
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.binder.MeterBinder;
import org.alfresco.solr.AlfrescoCoreAdminHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.management.MBeanServer;

public class SolrMetrics implements MeterBinder {

AlfrescoCoreAdminHandler coreAdminHandler;
Copy link
Contributor

Choose a reason for hiding this comment

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

should be private ?

Copy link
Contributor Author

@anghelutar anghelutar Mar 19, 2021

Choose a reason for hiding this comment

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

Why? It is used outside package.

Copy link
Contributor

Choose a reason for hiding this comment

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

I don't see any package-usages ? 🤷

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's used by eu.xenit.alfred.telemetry.solr.monitoring.handler.MicrometerHandler, outside the package.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Will merge now and come back to this later if needed

Copy link
Contributor

Choose a reason for hiding this comment

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

If used elsewhere, please create and use an accessor.

https://stackoverflow.com/a/1568230

MBeanServer mBeanServer;

Logger logger = LoggerFactory.getLogger(SolrMetrics.class);

public SolrMetrics(AlfrescoCoreAdminHandler coreAdminHandler, MBeanServer mBeanServer) {
this.coreAdminHandler = coreAdminHandler;
this.mBeanServer = mBeanServer;
}

@Override
public void bindTo(MeterRegistry registry) {
if(Util.isEnabled("METRICS_SOLR_CORESTATS_ENABLED"))
Copy link
Contributor

@kerkhofsd kerkhofsd Mar 22, 2021

Choose a reason for hiding this comment

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

new SolrCoreStatsMetrics(coreAdminHandler).bindTo(registry);
if(Util.isEnabled("METRICS_SOLR_FTS_ENABLED"))
new SolrFTSMetrics(coreAdminHandler).bindTo(registry);
if(Util.isEnabled("METRICS_SOLR_TRACKER_ENABLED"))
new SolrTrackerMetrics(coreAdminHandler).bindTo(registry);
if(Util.isEnabled("METRICS_SOLR_JMX_ENABLED"))
new SolrBeansMetrics(mBeanServer).bindTo(registry);
}
}
4 changes: 3 additions & 1 deletion alfred-telemetry-solr/alfred-telemetry-solr6/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,14 @@ dependencies {
exclude group: 'org.restlet.jee' // Only available in JCenter, not essential in this project.
}
alfrescoProvided "org.alfresco:alfresco-search:${assVersion}"
alfrescoProvided "org.alfresco:alfresco-solrclient-lib:${assVersion}"
}

createDockerFile {
from "${solrBaseImage}"

smartCopy "${rootProject.projectDir}/integration-tests/src/test/resources/${solrFlavor}/solrconfig_insight.xml", "/opt/alfresco-search-services/solrhome/templates/rerank/conf/solrconfig_insight.xml"
smartCopy "${rootProject.projectDir}/integration-tests/src/test/resources/${solrFlavor}/95-init-solr-micrometer-metrics.sh", "/docker-entrypoint.d/"
smartCopy "${rootProject.projectDir}/integration-tests/src/test/resources/${solrFlavor}/solrconfig.xml", "/opt/alfresco-search-services/solrhome/templates/rerank/conf/solrconfig.xml"
smartCopy "${rootProject.projectDir}/integration-tests/src/test/resources/${solrFlavor}/jetty.xml", "/opt/alfresco-search-services/solr/server/etc/jetty.xml"
smartCopy "${rootProject.projectDir}/integration-tests/src/test/resources/${solrFlavor}/solr-jetty-context.xml", "/opt/alfresco-search-services/solr/server/contexts/solr-jetty-context.xml"
smartCopy shadowJar.outputs.files, "/opt/alfresco-search-services/solrhome/lib/"
Expand Down
8 changes: 5 additions & 3 deletions alfred-telemetry-solr/alfred-telemetry-solr6/overload.gradle
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
ext {
solrVersion = '6.6.5'
assVersion = '1.4.0'
solrBaseImage = 'docker.io/xenit/alfresco-solr6:1.4.0'
//assVersion = '1.4.0'
//solrBaseImage = 'hub.xenit.eu/alfresco-enterprise/alfresco-solr6:1.4.0'
assVersion = '2.0.0'
solrBaseImage = 'hub.xenit.eu/alfresco-enterprise/alfresco-solr6:2.0.0'
solrFlavor = 'solr6'
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
package eu.xenit.alfred.telemetry.solr.monitoring.binder;

import eu.xenit.alfred.telemetry.solr.util.Util;
import io.micrometer.core.instrument.Gauge;
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.Tags;
import io.micrometer.core.instrument.binder.MeterBinder;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Map.Entry;
import java.util.Set;
import org.alfresco.solr.AlfrescoCoreAdminHandler;
import org.alfresco.solr.tracker.TrackerRegistry;
import org.apache.solr.common.util.NamedList;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class SolrFTSMetrics implements MeterBinder {

AlfrescoCoreAdminHandler coreAdminHandler;
MeterRegistry registry;

Logger logger = LoggerFactory.getLogger(SolrFTSMetrics.class);

public SolrFTSMetrics(AlfrescoCoreAdminHandler coreAdminHandler) {
this.coreAdminHandler = coreAdminHandler;
}

private void registerFTSMetrics() {
logger.info("Registering FTS metrics");
TrackerRegistry trackerRegistry = coreAdminHandler.getTrackerRegistry();

while (trackerRegistry.getCoreNames().size() == 0) {
logger.error("Solr did not start tracking yet, waiting 10sec");
try {
Thread.currentThread().sleep(10_000);
trackerRegistry = coreAdminHandler.getTrackerRegistry();
} catch (InterruptedException e) {
e.printStackTrace();
Copy link
Contributor

Choose a reason for hiding this comment

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

Use a logger to log catched exceptions.

}
}

Set<String> coreNames = coreAdminHandler.getTrackerRegistry().getCoreNames();
for (String coreName : coreNames) {
Object server = coreAdminHandler.getInformationServers().get(coreName);
NamedList<Object> report = new NamedList();
Method method = null;
try {
Class<?> solrInformationServerClass = Class.forName("org.alfresco.solr.SolrInformationServer");
Class<?>[] partypes = new Class[]{NamedList.class};
if(Util.isVersionLowerThan2()) {
method = solrInformationServerClass.getMethod("addFTSStatusCounts", partypes);
} else {
method = solrInformationServerClass.getMethod("addContentOutdatedAndUpdatedCounts", partypes);
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
Object[] arglist = new Object[1];
arglist[0] = report;
try {
method.invoke(server, arglist);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}

// Keys in ASS >= 2.0.0
Tags tags = Tags.of("core", coreName, "state", "InSync");
Gauge.builder("alfresco.fts", server, x -> getValueFromReport(server, "Node count whose content is in sync"))
.tags(tags)
.register(registry);

tags = Tags.of("core", coreName, "state", "ToBeUpdated");
Gauge.builder("alfresco.fts", server, x -> getValueFromReport(server, "Node count whose content needs to be updated"))
.tags(tags)
.register(registry);

// Keys in ASS < 2.0.0
tags = Tags.of("core", coreName, "state", "Clean");
Gauge.builder("alfresco.fts", server, x -> getValueFromReport(server, "Node count with FTSStatus Clean"))
.tags(tags)
.register(registry);

tags = Tags.of("core", coreName, "state", "Dirty");
Gauge.builder("alfresco.fts", server, x -> getValueFromReport(server, "Node count with FTSStatus Dirty"))
.tags(tags)
.register(registry);

tags = Tags.of("core", coreName, "state", "New");
Gauge.builder("alfresco.fts", server, x -> getValueFromReport(server, "Node count with FTSStatus New"))
.tags(tags)
.register(registry);

}
}

private long getValueFromReport(Object server, String key) {
NamedList<Object> report = new NamedList();
Method method = null;
try {
Class<?> solrInformationServerClass = Class.forName("org.alfresco.solr.SolrInformationServer");
Class<?>[] partypes = new Class[]{NamedList.class};
if(Util.isVersionLowerThan2()) {
method = solrInformationServerClass.getMethod("addFTSStatusCounts", partypes);
} else {
method = solrInformationServerClass.getMethod("addContentOutdatedAndUpdatedCounts", partypes);
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
Object[] arglist = new Object[1];
arglist[0] = report;
try {
method.invoke(server, arglist);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}

for (Entry fts : report) {
if (fts.getKey().equals(key)) {
return Long.parseLong(fts.getValue().toString());
}
}
return -1;
}


@Override
public void bindTo(MeterRegistry registry) {
this.registry = registry;
registerFTSMetrics();
}
}
Loading