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

Add ability to get raw request / response for audit log #73

Open
jxtps opened this issue Apr 22, 2014 · 6 comments
Open

Add ability to get raw request / response for audit log #73

jxtps opened this issue Apr 22, 2014 · 6 comments
Labels

Comments

@jxtps
Copy link

jxtps commented Apr 22, 2014

For auditing purposes we need to log every single call made to Stripe, and precisely what was sent and what was received back (yes, I'm aware of your corresponding log, that is unfortunately not sufficient here).

Currently it is not possible to get that information - as soon as _request returns it is dropped on the floor: https://github.com/stripe/stripe-java/blob/master/src/main/java/com/stripe/net/APIResource.java#L418

It would be great if that capability could be added - would be unfortunate to have to roll our own SDK "just" to get that.

Thanks!

@jimdanz
Copy link
Contributor

jimdanz commented Apr 24, 2014

Could you elaborate on why our dashboard logs are not sufficient for your use case?

In terms of stripe-java:
For all StripeObjects, toString includes the a JSON representation of the object. It is true that this this is effectively re-serializing the deserialized data; it is not a true readback of the raw response.
The API parameters that you pass are also what go over the wire.

I'm a bit nervous to include the full request object in the StripeObject. Among other things, it'd include the api key that you made the request with. I may be overly paranoid, but I'm potentially not excited about objects that didn't used to have API keys in them now having API keys, depending on what kind of automatic serialization formats people might be using (I don't want to accidentally lead you to start injecting your Stripe secret key into your database just because you bumped your stripe-java dependency).

Anyway, I'm happy to entertain this. Would I be able to convince you to submit a pull request? I'll also note that short of rolling your own SDK, you'd in general always be welcome to fork stripe-java to add the request / response logging that you need. You wouldn't need to roll your own SDK.

Let me know your thoughts. If you're not up for taking a stab at adding what you need, could you describe the desired interface in a bit more detail? Would you expect that any fetched APIResource would be able to tell you about the request that created it?

@jxtps
Copy link
Author

jxtps commented Apr 24, 2014

Don't get me wrong - the Stripe dashboard log is outstanding and we've used it several times. The reason we need the logging "in-house" is 1. what if the call doesn't make it to stripe (network issue) - then your log can't show it, 2. we use multiple external APIs and track all calls to all APIs (including some internal stuff), 3. with all logging "internal" we're able to attach all sorts of reference information to each log entry - I can look up a user and see precisely what the sequence of API calls were, which helps a lot when trying to answer "why doesn't it work?"

The information can't really be put in the StripeObject returned by e.g. Charge.create() - there are several cases that require logging where such an object is not returned (e.g. the failure cases).

The strategy I've seen used by other SDKs is to not use a static method, but instead have a Client object created which handles the request and then returns the StripeObject if succesful, but regardless it holds on to the most recent request information (since separate Client objects can be created by separate threads, this can easily be used in a thread safe manner by the calling code).

So instead of Charge.create(params, apiKey), you'd have something along the lines of:

StripeClient client = new StripeClient(apiKey); 
try { 
  client.charge(params); 
} finally { 
  doLogging(client); // client now has e.g. lastRequest, lastResponse, lastStatus, etc
}

(specific implementations may do things slightly differently, but you get the general gist)

Under the hood, Charge.create(params, apiKey) can of course "just" do new StripeClient(apiKey).charge(params) for backwards compatibility.

I realize that this would be a significant departure from the current structure, at least under the hood.

Perhaps it would be an easier change to not to a StripeClient, but instead do a StripeCall, encapsulating a single call to Stripe. The usage would then be something like:

StripeCall call = Charge.createCall(params, apiKey); 
try { 
  call.execute(); 
} finally { 
  doLogging(call); // call now has e.g. lastRequest, lastResponse, lastStatus, etc
}

That would unfortunately duplicate the entire static method set, which is not super-exciting.

It's not easy to retrofit in a both clean and backwards compatible manner on the current SDK. Thoughts?

@kyleconroy
Copy link
Contributor

I think the correct approach here would be to abstract all connection logic into pluggable backends. You could then write a custom backend that extends the provided backend to write all requests / responses to your logging backend.

@kyleconroy
Copy link
Contributor

I'm going to close this issue for now, but tag it with version-two. We'll probably go with the backends approach, which means you'll be able to create a custom backend that would log all requests / responses.

@kyleconroy kyleconroy modified the milestone: Version 2 Sep 17, 2015
@kyleconroy
Copy link
Contributor

This issue has been added to the Version 2 Roadmap https://github.com/stripe/stripe-java/wiki/Roadmap

@kyleconroy kyleconroy reopened this Oct 2, 2015
@longlho
Copy link

longlho commented Aug 31, 2022

has there been any activity on this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants