Skip to content

Commit

Permalink
Merge pull request #22 from andrerod/tracing
Browse files Browse the repository at this point in the history
Add tracing framework
  • Loading branch information
André Rodrigues committed Dec 31, 2013
2 parents 9a37bcd + 2e5e270 commit 3493d8f
Show file tree
Hide file tree
Showing 529 changed files with 25,327 additions and 10,854 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,13 @@
import com.microsoft.windowsazure.core.pipeline.apache.HttpRequestInterceptorAdapter;
import com.microsoft.windowsazure.core.pipeline.filter.ServiceResponseFilter;
import com.microsoft.windowsazure.core.pipeline.apache.HttpResponseInterceptorAdapter;
import java.io.Closeable;
import java.io.IOException;
import java.util.concurrent.ExecutorService;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;

public abstract class ServiceClient<TClient> implements FilterableService<TClient> {
public abstract class ServiceClient<TClient> implements FilterableService<TClient>, Closeable {
private final ExecutorService executorService;

public ExecutorService getExecutorService() { return this.executorService; }
Expand Down Expand Up @@ -78,4 +80,10 @@ public TClient withResponseFilterLast(ServiceResponseFilter serviceResponseFilte
httpClientBuilder.addInterceptorLast(new HttpResponseInterceptorAdapter(serviceResponseFilter));
return this.newInstance(httpClientBuilder, executorService);
}

@Override
public void close() throws IOException
{
httpClient.close();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,5 @@
package com.microsoft.windowsazure.core;

public interface ServiceOperations<TClient> {
TClient getClient();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/**
* Copyright Microsoft Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.microsoft.windowsazure.tracing;

import com.microsoft.windowsazure.core.pipeline.filter.ServiceRequestContext;
import com.microsoft.windowsazure.core.pipeline.filter.ServiceRequestFilter;
import com.microsoft.windowsazure.core.pipeline.filter.ServiceResponseContext;
import com.microsoft.windowsazure.core.pipeline.filter.ServiceResponseFilter;

public class ClientRequestTrackingHandler implements ServiceRequestFilter, ServiceResponseFilter {
private final String trackingId;

public String getTrackingId() { return trackingId; }

public ClientRequestTrackingHandler(String trackingId)
{
this.trackingId = trackingId;
}

@Override
public void filter (ServiceRequestContext request)
{
request.setHeader("client-tracking-id", trackingId);
}

@Override
public void filter (ServiceRequestContext request, ServiceResponseContext response)
{
response.setHeader("client-tracking-id", trackingId);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,222 @@
/**
* Copyright Microsoft Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.microsoft.windowsazure.tracing;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;

/**
* Provides tracing utilities that insight into all aspects of client
* operations via implementations of the ICloudTracingInterceptor
* interface. All tracing is global.
*/
public class CloudTracing {
/**
* The collection of tracing interceptors to notify.
*/
private static final List<CloudTracingInterceptor> interceptors;

/**
* Gets the collection of tracing interceptors to notify.
*
* @return the collection of tracing interceptors.
*/
static List<CloudTracingInterceptor> getInterceptors()
{
return interceptors;
}

/**
* Gets a value indicating whether tracing is enabled.
* Tracing can be disabled for performance.
*/
private static boolean isEnabled;

/**
* Gets the value indicating whether tracing is enabled.
*
* @return Boolean value indicating if tracing is enabled.
*/
public static boolean getIsEnabled()
{
return isEnabled;
}

/**
* Sets the value indicating whether tracing is enabled.
*
* @param enabled Boolean value indicating if tracing is enabled.
*/
public static void setIsEnabled(boolean enabled)
{
isEnabled = enabled;
}

static
{
isEnabled = true;
interceptors = Collections.synchronizedList(new ArrayList<CloudTracingInterceptor>());
}

/**
* Add a tracing interceptor to be notified of changes.
*
* @param cloudTracingInterceptor The tracing interceptor.
*/
public static void addTracingInterceptor(CloudTracingInterceptor cloudTracingInterceptor)
{
if (cloudTracingInterceptor == null)
{
throw new NullPointerException();
}

interceptors.add(cloudTracingInterceptor);
}

/**
* Remove a tracing interceptor from change notifications.
*
* @param cloudTracingInterceptor The tracing interceptor.
* @return True if the tracing interceptor was found and removed; false
* otherwise.
*/
public static boolean removeTracingInterceptor(CloudTracingInterceptor cloudTracingInterceptor)
{
if (cloudTracingInterceptor == null)
{
throw new NullPointerException();
}

return interceptors.remove(cloudTracingInterceptor);
}

private static long nextInvocationId = 0;

public static long getNextInvocationId()
{
return ++nextInvocationId;
}

public static void information(String message, Object... parameters)
{
if (isEnabled)
{
information(String.format(message, parameters));
}
}

public static void configuration(String source, String name, String value)
{
if (isEnabled)
{
synchronized (interceptors)
{
for (CloudTracingInterceptor writer: interceptors)
{
writer.configuration(source, name, value);
}
}
}
}

public static void information(String message)
{
if (isEnabled)
{
synchronized (interceptors)
{
for (CloudTracingInterceptor writer: interceptors)
{
writer.information(message);
}
}
}
}

public static void enter(String invocationId, Object instance, String method, HashMap<String, Object> parameters)
{
if (isEnabled)
{
synchronized (interceptors)
{
for (CloudTracingInterceptor writer: interceptors)
{
writer.enter(invocationId, instance, method, parameters);
}
}
}
}

public static void sendRequest(String invocationId, HttpRequest request)
{
if (isEnabled)
{
synchronized (interceptors)
{
for (CloudTracingInterceptor writer: interceptors)
{
writer.sendRequest(invocationId, request);
}
}
}
}

public static void receiveResponse(String invocationId, HttpResponse response)
{
if (isEnabled)
{
synchronized (interceptors)
{
for (CloudTracingInterceptor writer: interceptors)
{
writer.receiveResponse(invocationId, response);
}
}
}
}

public static void error(String invocationId, Exception ex)
{
if (isEnabled)
{
synchronized (interceptors)
{
for (CloudTracingInterceptor writer: interceptors)
{
writer.error(invocationId, ex);
}
}
}
}

public static void exit(String invocationId, Object result)
{
if (isEnabled)
{
synchronized (interceptors)
{
for (CloudTracingInterceptor writer: interceptors)
{
writer.exit(invocationId, result);
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/**
* Copyright Microsoft Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.microsoft.windowsazure.tracing;

import java.util.HashMap;
import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;

/**
* The CloudTracingInterceptor provides useful information about cloud
* operations. Interception is global and a tracing interceptor can be
* added via CloudContext.Configuration.Tracing.AddTracingInterceptor.
*/
public interface CloudTracingInterceptor
{
/**
* Trace information.
*
* @param message The information to trace.
*/
void information(String message);

/**
* Probe configuration for the value of a setting.
*
* @param source The configuration source.
* @param name The name of the setting.
* @param value The value of the setting in the source.
*/
void configuration(String source, String name, String value);

/**
* Enter a method.
*
* @param invocationId Method invocation identifier.
* @param instance The instance with the method.
* @param method Name of the method.
* @param parameters Method parameters.
*/
void enter(String invocationId, Object instance, String method, HashMap<String, Object> parameters);

/**
* Send an HTTP request.
*
* @param invocationId Method invocation identifier.
* @param request The request about to be sent.
*/
void sendRequest(String invocationId, HttpRequest request);

/**
* Receive an HTTP response.
*
* @param invocationId Method invocation identifier.
* @param response The response instance.
*/
void receiveResponse(String invocationId, HttpResponse response);

/**
* Raise an error.
*
* @param invocationId Method invocation identifier.
* @param exception The error.
*/
void error(String invocationId, Exception exception);

/**
* Exit a method. Note: Exit will not be called in the event of an
* error.
*
* @param invocationId Method invocation identifier.
* @param returnValue Method return value.
*/
void exit(String invocationId, Object returnValue);
}
Loading

0 comments on commit 3493d8f

Please sign in to comment.