StackExchange.Redis writes log messages to a TextWriter. It does not use the ILogger interface for logging.
I would like to turn messages written to a TextWriter, into Serilog debug level messages.
Thoughts?
Something like the following (only smoke tested, but seems to work):
public class TextWriterLogger : TextWriter
{
private ILogger logger;
private StringBuilder builder = new StringBuilder();
private bool terminatorStarted = false;
public TextWriterLogger(ILoggerFactory log)
{
logger = log.CreateLogger("RedisTrace");
}
public override void Write(string value)
{
logger.LogDebug(value);
}
public override void Write(char value)
{
builder.Append(value);
if (value == NewLine[0])
if (NewLine.Length == 1)
Flush2Log();
else
terminatorStarted = true;
else if (terminatorStarted)
if (terminatorStarted = NewLine[1] == value)
Flush2Log();
}
private void Flush2Log()
{
if (builder.Length > NewLine.Length)
logger.LogDebug(builder.ToString());
builder.Clear();
terminatorStarted = false;
}
public override Encoding Encoding
{
get { return Encoding.Default; }
}
}
Related
I tried to write a udf function to calculate my data. In the trino's docs, I knew I should to write a function plugin and I succeed to execute my udf aggregate function sql.
But when I write sql with aggregate function and window function, the sql executed failed.
The error log is com.google.common.util.concurrent.ExecutionError: java.lang.NoClassDefFoundError: com/example/ListState.
I think I may implement the interface about the window function.
The ListState.java file code
#AccumulatorStateMetadata(stateSerializerClass = ListStateSerializer.class, stateFactoryClass = ListStateFactory.class)
public interface ListState extends AccumulatorState {
List<String> getList();
void setList(List<String> value);
}
The ListStateSerializer file code
public class ListStateSerializer implements AccumulatorStateSerializer<ListState>
{
#Override
public Type getSerializedType() {
return VARCHAR;
}
#Override
public void serialize(ListState state, BlockBuilder out) {
if (state.getList() == null) {
out.appendNull();
return;
}
String value = String.join(",", state.getList());
VARCHAR.writeSlice(out, Slices.utf8Slice(value));
}
#Override
public void deserialize(Block block, int index, ListState state) {
String value = VARCHAR.getSlice(block, index).toStringUtf8();
List<String> list = Arrays.asList(value.split(","));
state.setList(list);
}
}
The ListStateFactory file code
public class ListStateFactory implements AccumulatorStateFactory<ListState> {
public static final class SingleListState implements ListState {
private List<String> list = new ArrayList<>();
#Override
public List<String> getList() {
return list;
}
#Override
public void setList(List<String> value) {
list = value;
}
#Override
public long getEstimatedSize() {
if (list == null) {
return 0;
}
return list.size();
}
}
public static class GroupedListState implements GroupedAccumulatorState, ListState {
private final ObjectBigArray<List<String>> container = new ObjectBigArray<>();
private long groupId;
#Override
public List<String> getList() {
return container.get(groupId);
}
#Override
public void setList(List<String> value) {
container.set(groupId, value);
}
#Override
public void setGroupId(long groupId) {
this.groupId = groupId;
if (this.getList() == null) {
this.setList(new ArrayList<String>());
}
}
#Override
public void ensureCapacity(long size) {
container.ensureCapacity(size);
}
#Override
public long getEstimatedSize() {
return container.sizeOf();
}
}
#Override
public ListState createSingleState() {
return new SingleListState();
}
#Override
public ListState createGroupedState() {
return new GroupedListState();
}
}
Thanks for help!!!!
And I found the WindowAccumulator class in the trino source code. But I don't know how to use it.
How to create a aggregate function for window function?
I have started working on a Freemarker Debugger using breakpoints etc. The supplied framework is based on java RMI. So far I get it to suspend at one breakpoint but then ... nothing.
Is there a very basic example setup for the serverpart and the client part other then the debug/imp classes supplied with the sources. That would be of great help.
this is my server class:
class DebuggerServer {
private final int port;
private final String templateName1;
private final Environment templateEnv;
private boolean stop = false;
public DebuggerServer(String templateName) throws IOException {
System.setProperty("freemarker.debug.password", "hello");
port = SecurityUtilities.getSystemProperty("freemarker.debug.port", Debugger.DEFAULT_PORT).intValue();
System.setProperty("freemarker.debug.password", "hello");
Configuration cfg = new Configuration();
// Some other recommended settings:
cfg.setIncompatibleImprovements(new Version(2, 3, 20));
cfg.setDefaultEncoding("UTF-8");
cfg.setLocale(Locale.US);
cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
Template template = cfg.getTemplate(templateName);
templateName1 = template.getName();
System.out.println("Debugging " + templateName1);
Map<String, Object> root = new HashMap();
Writer consoleWriter = new OutputStreamWriter(System.out);
templateEnv = new Environment(template, null, consoleWriter);
DebuggerService.registerTemplate(template);
}
public void start() {
new Thread(new Runnable() {
#Override
public void run() {
startInternal();
}
}, "FreeMarker Debugger Server Acceptor").start();
}
private void startInternal() {
boolean handled = false;
while (!stop) {
List breakPoints = DebuggerService.getBreakpoints(templateName1);
for (int i = 0; i < breakPoints.size(); i++) {
try {
Breakpoint bp = (Breakpoint) breakPoints.get(i);
handled = DebuggerService.suspendEnvironment(templateEnv, templateName1, bp.getLine());
} catch (RemoteException e) {
System.err.println(e.getMessage());
}
}
}
}
public void stop() {
this.stop = true;
}
}
This is the client class:
class DebuggerClientHandler {
private final Debugger client;
private boolean stop = false;
public DebuggerClientHandler(String templateName) throws IOException {
// System.setProperty("freemarker.debug.password", "hello");
// System.setProperty("java.rmi.server.hostname", "192.168.2.160");
client = DebuggerClient.getDebugger(InetAddress.getByName("localhost"), Debugger.DEFAULT_PORT, "hello");
client.addDebuggerListener(environmentSuspendedEvent -> {
System.out.println("Break " + environmentSuspendedEvent.getName() + " at line " + environmentSuspendedEvent.getLine());
// environmentSuspendedEvent.getEnvironment().resume();
});
}
public void start() {
new Thread(new Runnable() {
#Override
public void run() {
startInternal();
}
}, "FreeMarker Debugger Server").start();
}
private void startInternal() {
while (!stop) {
}
}
public void stop() {
this.stop = true;
}
public void addBreakPoint(String s, int i) throws RemoteException {
Breakpoint bp = new Breakpoint(s, i);
List breakpoints = client.getBreakpoints();
client.addBreakpoint(bp);
}
}
Liferay IDE (https://github.com/liferay/liferay-ide) has FreeMarker template debug support (https://issues.liferay.com/browse/IDE-976), so somehow they managed to use it. I have never seen it in action though. Other than that, I'm not aware of anything that uses the debug API.
I want to hook all method of ViewGroup, so write below code:
final Class<?> mViewGroup = XposedHelpers.findClass("android.view.ViewGroup", lpparam.classLoader);
for (final Method method : mViewGroup.getDeclaredMethods()) {
if (true == Modifier.isAbstract(method.getModifiers())){
XposedBridge.log("skip abstract:" + method.getName());
continue;
}
XposedBridge.log("----" + method.getName());
XposedBridge.hookMethod(method, methodHook);
}
final StringBuilder sb = new StringBuilder();
XC_MethodHook methodHook = new XC_MethodHook() {
#Override
protected void beforeHookedMethod(XC_MethodHook.MethodHookParam param) throws Throwable {
dumpParams(param);
}
#Override
protected void afterHookedMethod(XC_MethodHook.MethodHookParam param) throws Throwable {
//param.setResult(false);
XposedBridge.log("after:" + param.getResult());
}
};
private void dumpParams(XC_MethodHook.MethodHookParam param) {
sb.setLength(0);
sb.append(param.method.getName()).append("(");
for (Object o:param.args) {
String typnam = "";
String value = "null";
if (o != null) {
typnam = o.getClass().getName();
value = o.toString();
}
sb.append(typnam).append(":").append(value).append(", ");
}
XposedBridge.log(sb.toString());
}
But when I run it, hook class sounds fine, but when execute it crashed at android.view.View$AttachInfo:
am_crash: `java.lang.IllegalAccessError,Illegal class access: 'EdHooker45' attempting to access 'android.view.View$AttachInfo' (declaration of 'EdHooker45' appears in /data/user_de/0/.../1129433416.jar),NULL,120]`
My aspect:
[Serializable]
class FlowController : OnMethodBoundaryAspect
{
[ThreadStatic]
private static bool logging;
public override void OnEntry(MethodExecutionArgs args)
{
if (logging)
return;
try
{
logging = true;
if (ProgramState.State() == false)
{
args.ReturnValue = ""; // WHAT DO I SET HERE?
args.FlowBehavior = FlowBehavior.Return;
}
}
finally
{
logging = false;
}
}
}
Basically the ProgramState.State() method checks if the program is running(true),paused(loops while isPaused == true), stopped(false), this should control the if methods can run or not(basically a start pause/resume stop thing)
But sometimes i get nullreferences when returning from the method.
i am interested in knowing how can i set the return type to the default return type of the method.
It is tested with PostSharp 6.0.29
Before use it please check required null controls.
If method is async Task
public override void OnException(MethodExecutionArgs args)
{
var methodReturnType = ((System.Reflection.MethodInfo)args.Method).ReturnType;
var runtime = methodReturnType.GetRuntimeFields().FirstOrDefault(f => f.Name.Equals("m_result"));
//Only if return type has parameterless constructture (should be check before create)
var returnValue = Activator.CreateInstance(runtime.FieldType);
args.ReturnValue = returnValue;
}
And if method is not async
public override void OnException(MethodExecutionArgs args)
{
var methodReturnType = ((System.Reflection.MethodInfo)args.Method).ReturnType;
//Only if return type has parameterless constructture (should be check before create)
var returnValue = Activator.CreateInstance(methodReturnType);
args.ReturnValue = returnValue;
}
You can make your aspect class generic with the generic parameter representing the method return type. Then you need to create a method-level attribute that is also an aspect provider. The attribute will be applied to the user code and in turn it can provide the correct instance of the generic aspect.
[Serializable]
[MulticastAttributeUsage( MulticastTargets.Method )]
public class FlowControllerAttribute : MethodLevelAspect, IAspectProvider
{
public IEnumerable<AspectInstance> ProvideAspects(object targetElement)
{
MethodInfo method = (MethodInfo) targetElement;
Type returnType = method.ReturnType == typeof(void)
? typeof(object)
: method.ReturnType;
IAspect aspect = (IAspect) Activator.CreateInstance(typeof(FlowControllerAspect<>).MakeGenericType(returnType));
yield return new AspectInstance(targetElement, aspect);
}
}
[Serializable]
public class FlowControllerAspect<T> : IOnMethodBoundaryAspect
{
public void RuntimeInitialize(MethodBase method)
{
}
public void OnEntry(MethodExecutionArgs args)
{
args.ReturnValue = default(T);
args.FlowBehavior = FlowBehavior.Return;
}
public void OnExit(MethodExecutionArgs args)
{
}
public void OnSuccess(MethodExecutionArgs args)
{
}
public void OnException(MethodExecutionArgs args)
{
}
}
// Usage:
[FlowController]
public int Method()
{
// ...
}
How can I add terminate button to eclipse console toolbar? I create console in this way:
IOConsole console = new IOConsole( name, null, null, true );
ConsolePlugin.getDefault().getConsoleManager().addConsoles( new IConsole[]{console} );
I found solution. Here is the code:
<extension
point="org.eclipse.ui.console.consolePageParticipants">
<consolePageParticipant
class="com.plugin.console.ConsoleActions"
id="com.plugin.console.PageParticipant">
<enablement>
<instanceof value="com.plugin.console.Console"/>
</enablement>
</consolePageParticipant>
</extension>
Console class:
public class Console extends IOConsole {
public Console(String name, ImageDescriptor imageDescriptor) {
super(name, imageDescriptor);
}
public Console(String name, String consoleType, ImageDescriptor imageDescriptor, boolean autoLifeCycle) {
super(name, consoleType, imageDescriptor, autoLifeCycle);
}
}
Console Participant class:
public class ConsoleActions implements IConsolePageParticipant {
private IPageBookViewPage page;
private Action remove, stop;
private IActionBars bars;
private IConsole console;
#Override
public void init(final IPageBookViewPage page, final IConsole console) {
this.console = console;
this.page = page;
IPageSite site = page.getSite();
this.bars = site.getActionBars();
createTerminateAllButton();
createRemoveButton();
bars.getMenuManager().add(new Separator());
bars.getMenuManager().add(remove);
IToolBarManager toolbarManager = bars.getToolBarManager();
toolbarManager.appendToGroup(IConsoleConstants.LAUNCH_GROUP, stop);
toolbarManager.appendToGroup(IConsoleConstants.LAUNCH_GROUP,remove);
bars.updateActionBars();
}
private void createTerminateAllButton() {
ImageDescriptor imageDescriptor = ImageDescriptor.createFromFile(getClass(), "/icons/stop_all_active.gif");
this.stop = new Action("Terminate all", imageDescriptor) {
public void run() {
//code to execute when button is pressed
}
};
}
private void createRemoveButton() {
ImageDescriptor imageDescriptor = ImageDescriptor.createFromFile(getClass(), "/icons/remove_active.gif");
this.remove= new Action("Remove console", imageDescriptor) {
public void run() {
//code to execute when button is pressed
}
};
}
#Override
public void dispose() {
remove= null;
stop = null;
bars = null;
page = null;
}
#Override
public Object getAdapter(Class adapter) {
return null;
}
#Override
public void activated() {
updateVis();
}
#Override
public void deactivated() {
updateVis();
}
private void updateVis() {
if (page == null)
return;
boolean isEnabled = true;
stop.setEnabled(isEnabled);
remove.setEnabled(isEnabled);
bars.updateActionBars();
}
}